#include "Channels.h"
#include "ChannelManager.h"
#include "Resource.h"
#include "String.h"
#include "SharedPtr.h"
#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "ItemModelManager.h"
#include "WorldPacket.h"
#include "Users.h"
#include "UserManager.h"
#include "Towns.h"
#include "TownManager.h"
#include "Mails.h"
#include "MailManager.h"
#include "XMLData.h"
#include "Effects.h"
#include "EffectManager.h"
#include "EffectModels.h"
#include "EffectModelManager.h"
#include "Missions.h"
#include "MissionModels.h"
#include "Titles.h"
#include "WSSocketManager.h"
#include "GlobalCommonFunctons.h"
#include "ProtocolDealEnums.h"
#include "GameDefine.h"
#include LOGIC_MGR_PATH
#include XMLDATA_MGR_PATH
#include "GameDataEnum.h"
#include "GameGoodsManager.h"
#include "ProtocolsManager.h"
#include "OpcodesEx.h"
#include "VipCardManager.h"
#include "CenterBankManager.h"
#include "CenterClubManager.h"
#include "url.h"

#include "GameLibs.h"
#include "AIInterface.h"
#include "MJEnum.h"
#include "MJStruct.h"
// #include "GoldCoronal.h"

#ifdef CENTERMATCH
#include "CenterMatchManager.h"
#include "CenterMatchLogic.h"
#endif // CENTERMATCH


char * Base64Encode(const char * input, int length)  
{  
    BIO * bmem = NULL;  
    BIO * b64 = NULL;  
    BUF_MEM * bptr = NULL;  
	
    b64 = BIO_new(BIO_f_base64()); 
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);  
    
    bmem = BIO_new(BIO_s_mem());  
    b64 = BIO_push(b64, bmem);  
    BIO_write(b64, input, length);  
    BIO_flush(b64);  
    BIO_get_mem_ptr(b64, &bptr);  
  
    char * buff = (char *)malloc(bptr->length + 1);  
    memcpy(buff, bptr->data, bptr->length);  
    buff[bptr->length] = 0;  
  
    BIO_free_all(b64);  
	
    return buff;  
}  

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateSimplePacket(WorldPacket * packet, const uint16 protocol)
{
	if (!packet)
		return false;
	packet->clear();
	uint16 packlen = 4;
	packet->reserve(packlen);
	packet->SetOpcode(protocol);
	*packet << protocol << packlen;
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreatePongPacket(WorldPacket * packet, const uint32 serial)
{
	if (!packet)
		return false;

	packet->clear();
	uint16 packlen = 8;
	packet->reserve(packlen);
	packet->SetOpcode(SMSG_PONG);

	*packet << uint16(SMSG_PONG) << uint16(packlen) << uint32(serial);
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUserLoginPacket(WorldPacket * packet, const uint8 status)
{
	if (!packet)
		return false;
	packet->clear();
	uint16 packlen = 9;
	packet->reserve(packlen);
	packet->SetOpcode(SMSG_LOGIN);

	*packet << uint16(SMSG_LOGIN) << uint16(packlen)
		<< uint8(status)
		<< uint32(time(0)); // 时间戳

	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGoldsUpdatePacket(WorldPacket * packet, const uint32 golds)
{
	if (!packet)
		return false;
	packet->clear();
	uint16 packlen = 8;
	packet->reserve(packlen);
	packet->SetOpcode(SMSG_GOLDSUPDATE);
	*packet << uint16(SMSG_GOLDSUPDATE) << packlen
		<< golds; // 元宝
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateEnterTownPacket(WorldPacket * packet, const uint32 serial, const uint8 status)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(64);
	packet->SetOpcode(SMSG_ENTERROOM);
	*packet << uint16(SMSG_ENTERROOM) << uint16(0) << serial << status;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCommonGoHallOrTablePacket(WorldPacket * packet, const uint32 where)
{
	if (!packet)
		return false;
	
	packet->clear();
	// 预开辟空间
	packet->reserve(64);
	packet->SetOpcode(SMSG_NOTICETO_HALLORROOM);
	*packet << uint16(SMSG_NOTICETO_HALLORROOM) << uint32(where);
	
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateExitReturnHallPacket(WorldPacket * packet, const uint8 isOffline)
{
	return CreateSimplePacket(packet, SMSG_EXITTOHALL, isOffline);
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateActiveInfoPacket(WorldPacket * packet, ActiveInfo &info)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(128);
	packet->SetOpcode(SMSG_ACTIVEINFO);
	*packet << uint16(SMSG_ACTIVEINFO) << uint16(0)
		<< uint32(info.destId)
		<< uint32(info.type)
		<< uint32(info.data1)
		<< uint32(info.data2)
		<< uint32(info.data3)
		<< uint32(info.data4);
	AppendPacketString<uint16>(packet, info.sdata1);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateLocalMessagePacket(WorldPacket * packet, const String &content, const uint8 type)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_LOCALMESSAGE);
	*packet << uint16(SMSG_LOCALMESSAGE) << uint16(0)
		<< type;
	AppendPacketString<uint16>(packet, content);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateOpenBackpackPacket(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(128);
	packet->SetOpcode(SMSG_OPENBACKPACK);
	*packet << uint16(SMSG_OPENBACKPACK) << uint16(0);
	// 获取背包物品列表
	list<ItemPtr> lstItems;
	pChr->getItemsList(&lstItems);
	uint8 kind = 0;
	*packet << kind;
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for (; iter != iterEnd; ++iter)
	{
		if ((*iter)->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = (*iter)->model;
		if (model.isNull())
			continue;
		if(model->getUInt32Field("type") == 3)
			continue;
		*packet << uint32((*iter)->getUInt32Field("model_id")) // 模式ID
			<< uint32(model->getUInt32Field("id")) // 图标
			<< uint32((*iter)->getUInt32Field("num")); // 数量
		AppendPacketString<uint8>(packet, model->getStringField("name")); // 名称
		AppendPacketString<uint8>(packet, GetItemText((*iter), "desc")); // 功能描述
		AppendPacketString<uint8>(packet, model->getStringField("title"));	// 适用游戏
		++kind;
	}
	// 背包物品种类
	packet->SetOffset(4, kind);
	// 设置包真正的长度
	packet->SetLength(packet->size());

	return true;
}

// 兑换背包
bool ProtocolsManager::CreateExchangeBagPacket(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(128);
	packet->SetOpcode(SMSG_EXCHANGEBAG);
	*packet << uint16(SMSG_EXCHANGEBAG) << uint16(0);
	
	// 获取背包物品列表
	list<ItemPtr> lstItems;
	pChr->getItemsList(&lstItems);
	
	uint16 count = 0;
	*packet << count;
	
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for (; iter != iterEnd; ++iter)
	{
		if ((*iter)->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		
		ItemModelPtr & model = (*iter)->model;
		if (model.isNull())
			continue;
		
		if(model->getUInt32Field("type") != 3)
			continue;
		
		*packet << uint32((*iter)->getUInt32Field("model_id")) 				// 模式ID
				<< uint32((*iter)->getUInt32Field("num")) 					// 数量
				<< uint32((*iter)->getUInt32Field("handle_time"))			// 开始生效时间（0 表示一直有效）
				<< uint32((*iter)->getUInt32Field("destroy_time"));			// 道具失效时间（0 表示一直有效）
		AppendPacketString<uint16>(packet, model->getStringField("desc")); 	// json数据
		++count;
	}
	
	// 背包物品种类
	packet->SetOffset(4, count);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
// SMSG_UPDATEEXCHANGEITEMNUMBER = 0x0035, // 更新兑换背包道具数量
bool ProtocolsManager::CreateUpdateExchangeItemNumberPacket(WorldPacket * packet, const uint32 & item_id, const uint32 & model_id, const uint32 number, bool bDelete)
{
	if (!packet)
		return false;
	
	packet->clear();
	// 预开辟空间
	uint16 len = 12;
	packet->reserve(len);
	packet->SetOpcode(SMSG_UPDATEEXCHANGEITEMNUMBER);
	*packet << uint16(SMSG_UPDATEEXCHANGEITEMNUMBER) << len
			<< uint32(item_id)
			<< uint32(model_id)
			<< uint32(number)
			<< uint8(bDelete);
	
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUpdateItemNumberPacket(WorldPacket * packet, const uint32 itemModelId, const uint32 number)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	uint16 len = 12;
	packet->reserve(len);
	packet->SetOpcode(SMSG_UPDATEITEMNUMBER);
	*packet << uint16(SMSG_UPDATEITEMNUMBER) << len
		<< itemModelId
		<< number;

	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateAddNewItemPacket(WorldPacket * packet, ItemPtr &itemPtr)
{
	if (!packet || itemPtr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(128);
	packet->SetOpcode(SMSG_ADDNEWITEMINBAG);
	ItemModelPtr & model = itemPtr->model;
	if (model.isNull())
		return false;
	*packet << uint16(SMSG_ADDNEWITEMINBAG) << uint16(0)
		<< uint32(itemPtr->getUInt32Field("model_id")) 				// 模式ID
		<< uint32(model->getUInt32Field("id")) 						// 图标
		<< uint32(itemPtr->getUInt32Field("num")); 					// 数量
	AppendPacketString<uint8>(packet, model->getStringField("name")); 	// 名称
	AppendPacketString<uint8>(packet, GetItemText(itemPtr, "desc")); 	// 功能描述
	AppendPacketString<uint8>(packet, model->getStringField("title"));	// 适用游戏

	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetShopGoodsPacket(WorldPacket * packet, const uint8 shopType, const uint8 labelType, const uint8 allPage, const uint8 curPage, std::list<GameGoods*> & lstGoods)
{
	if (!packet)
		return false;
	packet->clear();
	uint8 num = 0;
	// 预开辟空间
	packet->reserve(256);
	packet->SetOpcode(SMSG_GETSHOPGOODSLIST);
	*packet << uint16(SMSG_GETSHOPGOODSLIST) << uint16(0)
		<< uint8(shopType)
		<< uint8(labelType)
		<< uint8(allPage)
		<< uint8(curPage)
		<< uint8(num);
	list<GameGoods*>::iterator iter = lstGoods.begin(), iterEnd = lstGoods.end();
	for (; iter != iterEnd; ++iter)
	{
		*packet << uint32((*iter)->goods_id) // 商品ID
			<< uint32((*iter)->id) // 图标
			<< uint32((*iter)->num) // 数量
			<< uint8((*iter)->flag) // 支付方式
			<< uint32((*iter)->org_price) // 原价
			<< uint32((*iter)->price); // 价格
		AppendPacketString<uint8>(packet, (*iter)->name); // 名称
		const ItemModelPtr & model = sItemModelMgr.load((*iter)->model_id);
		if (model.isNull())
		{
			AppendPacketString<uint8>(packet, ""); // 功能描述
			AppendPacketString<uint8>(packet, "");	// 适用游戏
		}
		else
		{
			AppendPacketString<uint8>(packet, model->getStringField("desc")); // 功能描述
			AppendPacketString<uint8>(packet, model->getStringField("title"));	// 适用游戏
		}
		++num;
	}
	// 设置物品数量
	packet->SetOffset(8, num);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateBuyGoodsPacket(WorldPacket * packet, const uint32 goodsId, const uint8 resultState, String strBillId)
{
	if (!packet)
		return false;
	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_BUYGOODS);
	*packet << uint16(SMSG_BUYGOODS) << uint16(0)
		<< goodsId // 商品ID
		<< resultState; // 结果
// 如果是实物，下发订单号
	AppendPacketString<uint8>(packet, strBillId);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetHallAndRoomNumberPacket(WorldPacket * packet, const uint32 &town_id)
{
	if (!packet)
		return false;
	packet->clear();
	// 获取房间列表
	// map<RoomType, BigRoom> mapRooms = sHallMgr.GetBigRoomMap();
	// 预开辟空间
	packet->reserve(256);
	packet->SetOpcode(SMSG_GETHALLPERSONS);
	*packet << uint16(SMSG_GETHALLPERSONS) << uint16(0);

	TownPtr pTown = sTownMgr.getByHandle(town_id);
	if (pTown.isNull())
		return false;
	*packet << uint32(pTown->getHandle())
		<< uint32(pTown->getUInt32Field("num"));
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateSystemSetPacket(WorldPacket * packet, UserPtr &pUser)
{
	if (!packet || pUser.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(256);
	packet->SetOpcode(SMSG_SYSTEMSET);
	*packet << uint16(SMSG_SYSTEMSET) << uint16(0);
	AppendPacketString<uint8>(packet, pUser->getStringField("config"));
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCommonSetPacket(WorldPacket * packet, UserPtr &pUser)
{
	if (!packet || pUser.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(256);
	packet->SetOpcode(SMSG_SAVECOMMONSET);
	*packet << uint16(SMSG_SAVECOMMONSET) << uint16(0);

	GameBank pubData;
	sBankMgr.GetPublicData(pUser, &pubData);

	AppendPacketString<uint8>(packet, pubData.sdata4);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetEffectsPacket(WorldPacket * packet, CharPtr &pChr, const uint8 & type, const uint32 & modelId)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 获取效果列表
	list<EffectPtr> lstEffects;
	if (NULL == pChr->getEffectsList(&lstEffects))
		return false;
	// 数量
	uint16 num = 0;
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_GETEFFECTS);
	*packet << uint16(SMSG_GETEFFECTS) << uint16(0)
		<< uint8(pChr->getTargetType()) << uint32(pChr->getHandle())
		<< num; // 数量
	list<EffectPtr>::iterator iter = lstEffects.begin(), iterEnd = lstEffects.end();
	for (; iter != iterEnd; ++iter)
	{
		if (0 == (*iter)->model->getUInt32Field("icon"))
			continue;
		if (type && type != (*iter)->model->getUInt32Field("type"))
			continue;
		if (modelId && modelId != (*iter)->model->getHandle())
			continue;

		*packet << uint32((*iter)->getHandle()) // ID
			<< uint32((*iter)->model->getHandle()) // 模式ID
			<< uint32((*iter)->model->getUInt32Field("type")) //效果类型
			<< uint32((*iter)->common.start_time) // 开始时间
			<< uint32((*iter)->common.end_time) // 结束时间
			<< uint32((*iter)->getUInt32Field("data1")) // 附加数据
			<< uint32((*iter)->getUInt32Field("data2"))
			<< uint32((*iter)->getUInt32Field("data3"))
			<< uint32((*iter)->getUInt32Field("data4"));

		++num;
	}
	packet->SetOffset(9, num);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateOperatorEffectsPacket(WorldPacket * packet, const uint8 objectType, const uint32 objectId, const uint8 opType, const uint8 resultState, ResourceProxy targetproxy)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_OPERATOROBJECT);
	*packet << uint16(SMSG_OPERATOROBJECT) << uint16(0)
		<< objectType
		<< objectId
		<< opType
		<< resultState
		<< (uint8)targetproxy.getTargetType()
		<< (uint32)targetproxy._handle;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetMailsListPacket(WorldPacket * packet, CharPtr &pChr, const uint8 status, const uint16 offset, const uint8 num)
{
	if (!packet || num == 0)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_GETMAILSLIST);
	*packet << uint16(SMSG_GETMAILSLIST) << uint16(0);
	// 获取邮件数量

	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return false;

	uint32 userid = pUser->getUInt32Field("platform_id");
	uint32 mailNum;
	std::list<GameMail> mailList;
	switch (status)
	{
	case en_MailListStatus_All:
	{
		uint32 time_now = time(0);
		mailNum = sChannelMgr.getMailDBCount("(`status` <> 255 AND `recv_serial` = %u) or \
										(`send_serial` = %u and `send_type` = %u and `expiration_time` > %u and `create_time` >= %u) \
										order by `create_time` desc", userid,
			pChr->getUInt32Field("gz_id"), en_MailSendType_AllServer,
			time_now, pUser->getUInt32Field("reg_time"));

		if (0 == mailNum || mailNum <= offset)
			break;

		sChannelMgr.getMailList(&mailList, offset, num, "(`status` <> 255 AND `recv_serial` = %u) or \
										(`send_serial` = %u and `send_type` = %u and `expiration_time` > %u and `create_time` >= %u) \
										order by `create_time` desc", userid,
			pChr->getUInt32Field("gz_id"), en_MailSendType_AllServer,
			time_now, pUser->getUInt32Field("reg_time"));
		break;
	}
	case en_MailListStatus_Readed: // 已读
	{
		mailNum = sChannelMgr.getMailDBCount("`recv_serial` = %u AND `status` = %u", userid, Mail::MailStatusOpen);
		if (0 == mailNum || mailNum <= offset)
			break;

		sChannelMgr.getMailList(&mailList, offset, num, "`recv_serial` = %u AND `status` = %u order by `create_time` desc", userid, Mail::MailStatusOpen);
		break;
	}
	case en_MailListStatus_Unread: // 未读
	{
		mailNum = sChannelMgr.getMailDBCount("`recv_serial` = %u AND `status` = %u", userid, Mail::MailStatusRecv);
		if (0 == mailNum || mailNum <= offset)
			break;

		sChannelMgr.getMailList(&mailList, offset, num, "`recv_serial` = %u AND `status` = %u order by `create_time` desc", userid, Mail::MailStatusRecv);
		break;
	}
	default:
		return false;
	}

	GameBank pBank;
	sBankMgr.GetPublicData(pUser, &pBank);
	if (pBank.bank_id == 0)
		return false;

	Json::Value json_mailTime = sBankMgr.GetUserDataJson(pBank, "MAILTIME");

	// 封装数据包
	*packet << uint8(status); 	// 邮件状态

	uint8 offSize = packet->size();
	uint16 realNum = mailNum;

	*packet << uint16(mailNum) 	// 总数
		<< uint16(offset) 	// 偏移量
		<< uint8(0); 		// 邮件数量

	uint32 count(0);
	std::list<GameMail>::iterator iter;
	for (iter = mailList.begin(); iter != mailList.end(); ++iter)
	{
		// 判断是否有已经领取过全服邮件
		if ((*iter).send_type == en_MailSendType_AllServer)
		{
			if (json_mailTime.size())
			{
				bool bHasGetServerMail = false;
				for (Json::Value::iterator it = json_mailTime.begin(); it != json_mailTime.end(); ++it)
				{
					uint32 mail_id = StringConverter::parseUnsignedInt(it.key().asString());
					if ((*iter).mail_id == mail_id)
					{
						bHasGetServerMail = true;
						break;
					}
				}

				if (bHasGetServerMail)
					continue;
			}
		}

		*packet << uint32((*iter).mail_id) 	// ID
			<< uint8((*iter).status) 	// 状态
			<< uint8((*iter).data1) 	// 是否有附件
			<< uint8((*iter).data3); 	// 附件是否领取

		AppendPacketString<uint8>(packet, (*iter).title); 		// 标题
		AppendPacketString<uint16>(packet, (*iter).contenct); 	// 内容

		*packet << uint32((*iter).create_time)	 				// 创建时间
			<< uint32((*iter).expiration_time);				// 过期时间
		count++;
	}

	// 实际邮件数量
	packet->SetOffset(9, uint8(count));
	if (realNum != count)
	{
		realNum = count;
		packet->SetOffset(offSize, uint16(realNum));
	}

	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateOperatorMailResultPacket(WorldPacket * packet, const uint32 mailId, const uint8 operatorType, const uint8 result)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	uint16 len = 10;
	packet->reserve(len);
	packet->SetOpcode(SMSG_OPERATORMAIL);
	*packet << uint16(SMSG_OPERATORMAIL) << len
		<< mailId
		<< operatorType
		<< result;
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateSendMailContentPacket(WorldPacket * packet, GameMail &pMail)
{
	if (!packet || !pMail.mail_id)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_SENDMAILCONTENT);
	*packet << uint16(SMSG_SENDMAILCONTENT) << uint16(0)
		<< uint32(pMail.mail_id); // ID
	AppendPacketString<uint8>(packet, pMail.title); // 标题
	// 是否需要解密
	if (pMail.flag & 0x80)
	{
		AppendPacketString<uint16>(packet, common_decrypt(pMail.contenct));
	}
	else
		AppendPacketString<uint16>(packet, pMail.contenct); // 邮件内容
	*packet << uint32(pMail.create_time) // 创建时间
		<< uint8(pMail.status)  	// 邮件状态
		<< uint8(pMail.data1)  		// 是否有附件
		<< uint8(pMail.data3);  	// 附件是否领取
// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateSendUnreadMailNumberPacket(WorldPacket * packet, UserPtr &pUser)
{
	if (!packet || pUser.isNull())
		return false;

	GameBank pBank;
	sBankMgr.GetPublicData(pUser, &pBank);
	if (pBank.bank_id == 0)
		return false;

	packet->clear();
	// 获取邮件数量
	uint32 userid = pUser->getUInt32Field("platform_id");
	uint32 time_now = time(0);
	uint32 mailNum = sChannelMgr.getMailDBCount("(`status` = %u AND `recv_serial` = %u) or \
							(`send_serial` = %u and `send_type` = %u and `expiration_time` > %u and `create_time` >= %u) \
							order by `create_time` desc", Mail::MailStatusRecv, userid,
		pUser->getUInt32Field("gz_id"), en_MailSendType_AllServer,
		time_now, pUser->getUInt32Field("reg_time"));

	if (mailNum)
	{
		std::list<GameMail> mailList;
		sChannelMgr.getMailList(&mailList, 0, mailNum, "(`status` = %u AND `recv_serial` = %u) or \
					(`send_serial` = %u and `send_type` = %u and `expiration_time` > %u and `create_time` >= %u) \
					order by `create_time` desc", Mail::MailStatusRecv, userid,
			pUser->getUInt32Field("gz_id"), en_MailSendType_AllServer,
			time_now, pUser->getUInt32Field("reg_time"));

		Json::Value json_mailTime = sBankMgr.GetUserDataJson(pBank, "MAILTIME");
		mailNum = 0;
		std::list<GameMail>::iterator iter;
		for (iter = mailList.begin(); iter != mailList.end(); ++iter)
		{
			// 判断是否有已经领取过全服邮件
			if ((*iter).send_type == en_MailSendType_AllServer)
			{
				if (json_mailTime.size())
				{
					bool bHasGetServerMail = false;
					for (Json::Value::iterator it = json_mailTime.begin(); it != json_mailTime.end(); ++it)
					{
						uint32 mail_id = StringConverter::parseUnsignedInt(it.key().asString());
						if ((*iter).mail_id == mail_id)
						{
							bHasGetServerMail = true;
							break;
						}
					}

					if (bHasGetServerMail)
						continue;
				}
			}

			mailNum++;
		}

	}

	// uint32 mailNum = sChannelMgr.getMailDBCount("`recv_serial` = %u AND `status` = %u", pUser->getUInt32Field("platform_id"), Mail::MailStatusRecv);
	// 预开辟空间
	uint16 len = 6;
	packet->reserve(len);
	packet->SetOpcode(SMSG_SENDUNREADMAILNUMBER);
	*packet << uint16(SMSG_SENDUNREADMAILNUMBER) << len
		<< uint16(mailNum);

	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateChangeSecondPwdPacket(WorldPacket * packet, const uint8 result)
{
	return CreateReturnStatePacket(packet, SMSG_CHANGESECONDPWD, result);
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateValidateSecondPwdPacket(WorldPacket * packet, const uint8 result)
{
	return CreateReturnStatePacket(packet, SMSG_VALIDATESECONDPWD, result);
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateLoginQueuePacket(WorldPacket * packet, const uint32 position)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_LOGINQUEUE);
	*packet << uint16(SMSG_LOGINQUEUE) << uint16(0)
		<< position;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateChatMessagePacket(WorldPacket * packet, const uint8 & type, CharPtr & srcChr, const String & szContent, CharPtr & target, const uint32 & color)
{
	if (!packet || srcChr.isNull() || szContent == "" || szContent.size() > 256)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_CHATDATA);
	*packet << uint16(SMSG_CHATDATA) << uint16(0)
		<< type << (uint32)srcChr->getHandle(); // 发送方
	AppendPacketString<uint8>(packet, srcChr->getStringField("name"));

	*packet << uint32(target.isNull() ? 0 : target->getHandle());
	AppendPacketString<uint8>(packet, target.isNull() ? "" : target->getStringField("name"));

	*packet << color;
	AppendPacketString<uint16>(packet, szContent);
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateSingleLabaChatPacket(WorldPacket * packet, CharPtr & srcChr, const String & szContent)
{
	if (!packet || srcChr.isNull() || szContent == "")
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(512);
	packet->SetOpcode(SMSG_SINGLE_LABA_CHAT);
	*packet << uint16(SMSG_SINGLE_LABA_CHAT) << uint16(0)
		<< (uint32)srcChr->getHandle(); // 发送方
	AppendPacketString<uint8>(packet, srcChr->getStringField("name"));

	AppendPacketString<uint16>(packet, szContent);
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateDanMuInfoPacket(WorldPacket * packet, stDanMu danMu, const uint8 & result)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_DANMU);
	*packet << uint16(SMSG_DANMU) << uint16(0)
		<< uint32(danMu.char_id)	//弹幕序号
		<< uint16(danMu.pos)		//弹幕位置
		<< uint16(danMu.isVip);		//是否VIP

	AppendPacketString<uint8>(packet, danMu.srcName);	//发送源玩家昵称
	AppendPacketString<uint8>(packet, danMu.content);	//弹幕内容

	*packet << uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateDanMuHistoryPacket(WorldPacket * packet, std::vector<stDanMu> vDanMu)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_DANMU_HISTORY);
	*packet << uint16(SMSG_DANMU_HISTORY) << uint16(0)
		<< uint8(vDanMu.size());

	std::vector<stDanMu>::iterator iter, ei = vDanMu.end();
	for (iter = vDanMu.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).char_id)
			<< uint16((*iter).pos)
			<< uint16((*iter).isVip);

		AppendPacketString<uint8>(packet, (*iter).srcName);
		AppendPacketString<uint8>(packet, (*iter).content);
	}

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetBankInfoPacket(WorldPacket * packet, GameBank &bank)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_GETBANKCOINS);
	*packet << uint16(SMSG_GETBANKCOINS) << uint16(0);
	AppendPacketString<uint8>(packet, StringConverter::toString(bank.coins)); // 铜钱存款
	AppendPacketString<uint8>(packet, StringConverter::toString(bank.prize)); // 兑换券存款
	AppendPacketString<uint8>(packet, StringConverter::toString(bank.rrj)); // 代币存款
	AppendPacketString<uint8>(packet, StringConverter::toString(bank.march)); // 参赛券存款
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreatePutCoinsInBankPacket(WorldPacket * packet, const uint32 result, const uint32 type, const uint32 num)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_PUTCOINSINBANK);
	*packet << uint16(SMSG_PUTCOINSINBANK) << uint16(0)
		<< uint8(result)
		<< uint8(type)
		<< uint32(num);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateExchageTicketPacket(WorldPacket * packet, const uint8 result)
{
	return CreateReturnStatePacket(packet, SMSG_EXCHANGETICKET, result);
}

// SMSG_EXCHANGEGATEWAYGOODS = 0x005B,	// 兑换网关配置道具
bool ProtocolsManager::CreateExchangeGatewayGoodsPacket(WorldPacket * packet, const uint32 & prizes_id, const uint32 & num, 
												const uint32 & exchange_model_id, const uint32 & exchange_mode_num, const uint8 & result)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_EXCHANGEGATEWAYGOODS);
	*packet << uint16(SMSG_EXCHANGEGATEWAYGOODS) << uint16(0)
			<< uint32(prizes_id)
			<< uint32(num)
			<< uint32(exchange_model_id)
			<< uint32(exchange_mode_num)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUpdateFiguralPacket(WorldPacket * packet, const uint32 figuralId)
{

	return false;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetCoinsFromBankPacket(WorldPacket * packet, const uint32 result, const uint32 type, const uint32 num)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_GETCOINSFROMBANK);
	*packet << uint16(SMSG_GETCOINSFROMBANK) << uint16(0)
		<< uint8(result)
		<< uint8(type)
		<< uint32(num);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetBankHistoryPacket(WorldPacket * packet, const uint32 pId, const uint8 num, const uint16 page)
{
	if (!packet || pId == 0 || num == 0 || page == 0)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(1024);
	packet->SetOpcode(SMSG_GETBANKHISTORY);
	*packet << uint16(SMSG_GETBANKHISTORY) << uint16(0);
	// 获取历史记录数量
	uint32 allCount = sChannelMgr.getCenterLogDBCount("src_id = %u and (type = %u or type = %u) order by create_time desc", pId, 1, 2);
	uint32 offset = num * (page - 1);
	std::list<GameLog> lstLogs;
	if (allCount > offset)
	{
		sChannelMgr.getCenterLogList(&lstLogs, offset, num, "src_id = %u and (type = %u or type = %u) order by create_time desc", pId, 1, 2);
	}
	// 封装数据包
	*packet << uint32(allCount) // 总数
		<< uint32(offset) // 偏移量
		<< uint8(lstLogs.size()); // 本页数量
// char buf[256];
	std::list<GameLog>::iterator iter;
	for (iter = lstLogs.begin(); iter != lstLogs.end(); ++iter)
	{
		AppendPacketString<uint8>(packet, (*iter).create_time); // 创建时间
		*packet << uint8((*iter).type);	// 操作
		AppendPacketString<uint8>(packet, sXmlDataMgr.GetGzIdName((*iter).dest_id)); // 操作
		*packet << uint32((*iter).data1) << uint32((*iter).data2) << uint32((*iter).data3);	// 类型,数量,余额		
	}
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateReturnStatePacket(WorldPacket * packet, const uint16 protocol, const uint8 status)
{
	if (!packet)
		return false;
	packet->clear();
	uint16 packlen = 4;
	packet->SetOpcode(protocol);
	if (0 == status)
	{
		packet->reserve(packlen);
		*packet << protocol << packlen;
	}
	else
	{
		packlen = 5;
		packet->reserve(packlen);
		*packet << protocol << packlen << status;
	}
	return true;
}

//-----------------------------------------------------------------------
String ProtocolsManager::GetItemText(ItemPtr &itemPtr, const char* fieldName)
{
	if (itemPtr.isNull())
		return "";
	String content = itemPtr->getStringField(fieldName);
	if (content.empty())
	{
		if (itemPtr->model.isNull())
			return "";
		else
			return itemPtr->model->getStringField(fieldName);
	}
	else
		return content;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUnreadMailNumPacket(WorldPacket * packet, const uint32 & pid)
{
	if (!packet || pid == 0)
		return false;

	/* packet->clear();
	// 获取邮件数量
	uint32 mailNum = sChannelMgr.getMailDBCount("`recv_serial` = %u AND `status` = %u", pid, Mail::MailStatusRecv);
	// 预开辟空间
	uint16 packlen = 6;
	packet->reserve(packlen);
	packet->SetOpcode(SMSG_NEWMAILNUM);
	*packet << uint16(SMSG_NEWMAILNUM) << uint16(0)
			<< uint16(mailNum); */
			// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool 	ProtocolsManager::CreateYellowStatusUpdate(WorldPacket *packet, const uint8 & type)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_QQDIAMONDLEVEL);
	*packet << uint16(SMSG_QQDIAMONDLEVEL) << uint16(0);
	*packet << type;
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateTellToDoPacket(WorldPacket * packet, const uint32 optType, const uint32 data1, const uint32 data2, const uint32 data3/*  = 0 */, const uint32 data4/*  = 0 */)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(64);
	packet->SetOpcode(SMSG_TELLTODO);
	*packet << uint16(SMSG_TELLTODO) << uint16(0)
		<< optType
		<< data1
		<< data2
		<< data3
		<< data4;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetEffortListPacket(WorldPacket * packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(16);
	packet->SetOpcode(SMSG_GETEFFORTLIST);
	*packet << uint16(SMSG_GETEFFORTLIST) << uint16(0);
	using namespace AIScript;
	AICreatureBaseInterface *pAiChrInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if (!pAiChrInfe)
		return false;
	std::list<TitleInfo> lstTitle;
	pAiChrInfe->getTitlesList(&lstTitle);
	*packet << uint8(lstTitle.size()); // 获得称号的数量
	std::list<TitleInfo>::iterator iterTitle = lstTitle.begin();
	for (; iterTitle != lstTitle.end(); ++iterTitle)
	{
		*packet << uint16((*iterTitle).id) // id
			<< uint32((*iterTitle).create_time); // 时间
	}
	uint32 offset = 5 + 6 * lstTitle.size();
	*packet << uint8(0);
	std::list<EffectPtr> effects;
	pChr->getEffectsList(&effects);
	uint8 count = 0;
	std::list<EffectPtr>::iterator iter;
	for (iter = effects.begin(); iter != effects.end(); ++iter)
	{
		if ((*iter)->model->getUInt32Field("type") == 1)
		{
			++count;
			*packet << uint16((*iter)->model->getHandle()) // id
				<< uint16((*iter)->getUInt32Field("data1")); // 进度(已达到次数)
		}
	}
	packet->SetOffset(offset, count); // 未获得的称号数量
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetEffortJsonListPacket(WorldPacket * packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(16);
	packet->SetOpcode(SMSG_GETEFFORTLIST);
	*packet << uint16(SMSG_GETEFFORTLIST) << uint16(0);
	*packet << uint8(0);
	EffectPtr pEffLogic;
	std::list<EffectPtr> effects;
	pChr->getEffectsList(&effects);
	std::list<EffectPtr>::iterator iter, enditer = effects.end();
	for (iter = effects.begin(); iter != enditer; ++iter)
	{
		if ((*iter)->getUInt32Field("effect_model_id") == en_EffectLogicModel_Achievement)
		{
			pEffLogic = *iter;
			break;
		}
	}
	if (pEffLogic.isNull())
		return false;
	uint8 count = 0;
	String strJs = pEffLogic->getStringField("info");
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJs, root);
	for (uint32 i = 0; i != root.size(); ++i)
	{
		Json::Value child = root[i];
		uint16 modelId = child["id"].asUInt();
		// uint32 currNum = child["num"].asUInt();
		uint32 finish_time = child["finish_time"].asUInt();
		if (finish_time)
		{
			*packet << modelId << finish_time;
			count++;
		}
	}
	packet->SetOffset(4, count);
	uint32 offset = 5 + (6 * count);
	*packet << uint8(0);
	count = 0;
	for (uint32 i = 0; i != root.size(); ++i)
	{
		Json::Value child = root[i];
		uint16 modelId = child["id"].asUInt();
		uint16 currNum = child["num"].asUInt();
		uint32 finish_time = child["finish_time"].asUInt();
		if (!finish_time)
		{
			*packet << modelId << currNum;
			count++;
		}
	}
	packet->SetOffset(offset, count); // 未获得的称号数量
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

// 全数据成就列表信息
bool ProtocolsManager::CreateServerEffortListPacket(WorldPacket * packet, CharPtr & pChr, std::list<EffectPtr> & effort_list)
{
	if (!packet || pChr.isNull())
		return false;

	packet->clear();
	int8 packlen = 6;

	using namespace AIScript;
	AICreatureBaseInterface *pAiChrInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if (!pAiChrInfe)
		return false;
	std::list<TitleInfo> lstTitle;
	pAiChrInfe->getTitlesList(&lstTitle);

	uint16 num = 0;

	packet->SetOpcode(SMSG_SERVER_EFFORTLIST);
	*packet << uint16(SMSG_SERVER_EFFORTLIST) << uint16(packlen)
		<< uint32(pChr->getHandle())
		<< uint16(num);

	std::list<TitleInfo>::iterator iterTitle = lstTitle.begin();
	for (; iterTitle != lstTitle.end(); ++iterTitle)
	{
		EffectModelPtr model = sEffectModelMgr.getByHandle((*iterTitle).id);
		if (model.isNull())
			continue;

		*packet << uint32(model->getHandle())
			<< uint16(model->getUInt32Field("effect3"))	//成就点数
			<< uint32(model->getUInt32Field("effect2"))	//获得的铜钱
			<< uint8(en_EffectStatus_Bountyed)			//成就已领取
			<< uint8(model->getUInt32Field("class"))	//等级
			<< uint8(model->getUInt32Field("style"))	//类型
			<< uint32(1)
			<< uint32(1)
			<< uint32((*iterTitle).create_time);

		AppendPacketString<uint8>(packet, model->getStringField("name"));
		AppendPacketString<uint16>(packet, model->getStringField("desc"));
		++num;
	}

	std::list<EffectPtr>::iterator iter, ei = effort_list.end();
	for (iter = effort_list.begin(); iter != ei; ++iter)
	{
		if (((*iter)->model->getUInt32Field("flag") & 0x1) == 0)
			continue;

		*packet << uint32((*iter)->model->getHandle())
			<< uint16((*iter)->model->getUInt32Field("effect3"))
			<< uint32((*iter)->model->getUInt32Field("effect2"))
			<< uint8((*iter)->getUInt32Field("effect_type"))
			<< uint8((*iter)->model->getUInt32Field("class"))
			<< uint8((*iter)->model->getUInt32Field("style"))
			<< uint32((*iter)->getUInt32Field("data1"))
			<< uint32((*iter)->model->getUInt32Field("effect1"))
			<< uint32((*iter)->getUInt32Field("data3"));

		AppendPacketString<uint8>(packet, (*iter)->model->getStringField("name"));
		AppendPacketString<uint16>(packet, (*iter)->model->getStringField("desc"));
		++num;
	}

	packet->SetOffset(8, uint16(num));
	packet->SetLength(packet->size());

	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetNewEffortPacket(WorldPacket * packet, const uint32 effortId)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(16);
	packet->SetOpcode(SMSG_GETNEWEFFORT);
	*packet << uint16(SMSG_GETNEWEFFORT) << uint16(0)
		<< uint16(effortId)
		<< uint32(time(0));
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateEffortSignPacket(WorldPacket * packet, const uint8 & type, const uint32 & serial, const uint32 & time_now, String code)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VALIDATE_SIGN);
	*packet << uint16(SMSG_VALIDATE_SIGN) << uint16(8)
		<< uint8(type)
		<< uint32(serial)
		<< uint32(time_now)
		<< uint16(code.size());

	if (code.size())
		packet->Write((const uint8*)code.c_str(), code.size());

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUserGainPacket(WorldPacket * packet, const uint8 & type, const uint32 & data1,
	const uint32 & data2, const uint32 & data3)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_GETBONUS_OPERATOR);
	*packet << uint16(SMSG_GETBONUS_OPERATOR) << uint16(0);
	*packet << type << data1 << data2 << data3;

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUpdateEffortPacket(WorldPacket * packet, const uint32 & effortId, const uint8 & status,
	const uint32 & data1 /* = 0 */, const uint32 & data2 /* = 0 */)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_UPDATE_EFFORT);
	*packet << uint16(SMSG_UPDATE_EFFORT) << uint16(0);
	*packet << effortId << status << data1 << data2;

	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateEffortInfoPacket(WorldPacket * packet, EffectPtr & effect)
{
	if (!packet || effect.isNull())
		return false;

	packet->clear();

	EffectModelPtr model = effect->model;

	packet->SetOpcode(SMSG_SERVER_EFFORTINFO);
	*packet << uint16(SMSG_SERVER_EFFORTINFO)
		<< uint16(0)
		<< uint32(model->getHandle())//成就模式
		<< uint16(model->getUInt32Field("effect3"))//达成成就点数
		<< uint32(model->getUInt32Field("effect2"))//达成成就获得铜钱
		<< uint8(effect->getUInt32Field("effect_type"))//成就状态
		<< uint8(model->getUInt32Field("class"))//成就等级
		<< uint8(effect->model->getUInt32Field("style"))//成就类型
		<< uint32(effect->getUInt32Field("data1"))//当前完成次数
		<< uint32(effect->model->getUInt32Field("effect1"))//目标完成次数
		<< uint32(effect->getUInt32Field("data3"));//完成时间

	AppendPacketString<uint8>(packet, effect->model->getStringField("name"));
	AppendPacketString<uint16>(packet, effect->model->getStringField("desc"));

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetEffortBountyPacket(WorldPacket * packet, const uint32 & eff_model_id, const uint8 & result)
{
	if (!packet)
		return false;

	uint16 packlen = 10;
	packet->clear();

	packet->SetOpcode(SMSG_SERVER_EFFORTBOUNTY);
	*packet << uint16(SMSG_SERVER_EFFORTBOUNTY) << uint16(packlen)
		<< uint32(eff_model_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateNewTitlePacket(WorldPacket * packet, const uint32 modelId)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_GETNEWEFFORT);
	*packet << uint16(SMSG_GETNEWEFFORT) << uint16(0)
		<< modelId
		<< (uint32)time(0);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateNotifyPlayCoronalPacket(WorldPacket * packet, const uint8 timeout, const uint32 coins)
{
	if (!packet)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_NOTIFYPLAYCORONAL);
	*packet << uint16(SMSG_NOTIFYPLAYCORONAL) << uint16(0)
		<< timeout
		<< coins;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
/* bool ProtocolsManager::CreatePlayCoronalResultPacket(WorldPacket * packet, const uint8 result, const uint8 opt, GCPlayer *pgc)
{
	if(!packet || pgc == NULL)
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_PLAYCORONAL);
	*packet << uint16(SMSG_PLAYCORONAL) << uint16(0)
			<< result
			<< opt
			<< uint8(pgc->count)
			<< uint8(pgc->result)
			<< uint32(pgc->curCoins);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
} */

bool ProtocolsManager::CreateMissionListPacket(WorldPacket * packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(CMSG_MISSION_LIST);
	*packet << uint16(CMSG_MISSION_LIST) << uint16(0);

	std::list<MissionPtr> missions;
	pChr->getMissionsList(&missions);
	*packet << uint8(missions.size());
	std::list<MissionPtr>::iterator mi, endmi = missions.end();
	for (mi = missions.begin(); mi != endmi; ++mi)
	{
		AppendPacketString<uint8>(packet, (*mi)->model->getStringField("name"));
		*packet << uint32((*mi)->model->getHandle())
			<< uint32((*mi)->getHandle())
			<< (uint8)(*mi)->model->getUInt32Field("lv")
			<< (*mi)->model->getUInt32Field("data2")
			<< (*mi)->model->getUInt32Field("data3")
			<< (uint8)(*mi)->getMissionStatus()
			<< (*mi)->getUInt32Field("data1")
			<< (*mi)->model->getUInt32Field("data1");
	}
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateMissionPacket(WorldPacket * packet, MissionPtr & pMission)
{
	if (!packet || pMission.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_MISSION_UPDATE);
	*packet << uint16(SMSG_MISSION_UPDATE) << uint16(0);
	*packet << uint32(pMission->getHandle())
		<< (uint8)pMission->getMissionStatus()
		<< pMission->getUInt32Field("data1");

	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateMaJonMissionListPacket(WorldPacket * packet, std::vector<MaJonMission> missions, const bool bAnime)
{
	if (!packet || missions.empty())
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_MAJON_MISSIONLIST);
	*packet << uint16(SMSG_MAJON_MISSIONLIST) << uint16(0)
		<< uint8(bAnime)
		<< uint8(missions.size());

	std::vector<MaJonMission>::iterator iter, ei = missions.end();
	for (iter = missions.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).model_id)
			<< uint8((*iter).status)
			<< uint32((*iter).coins)
			<< uint32((*iter).hongbao);
		AppendPacketString<uint8>(packet, (*iter).sName);
		AppendPacketString<uint8>(packet, (*iter).sBounty);
		AppendPacketString<uint8>(packet, (*iter).sDesc);
	}

	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateMajonMissionComplatePacket(WorldPacket * packet, MaJonMission pMission)
{
	if (!packet || pMission.model_id == 0)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_MAJON_MISSIONBOUNT);
	*packet << uint16(SMSG_MAJON_MISSIONBOUNT) << uint16(0)
		<< uint32(pMission.model_id)
		<< uint32(pMission.coins)
		<< uint32(pMission.hongbao);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateSmallGameDataPacket(WorldPacket * packet, const uint8 & gameid, const uint8 & status,
	const uint8 & result, const uint32 & data1/*  = 0 */, const uint32 & data2/*  = 0 */)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_SMGAMEDATA);
	*packet << uint16(SMSG_SMGAMEDATA) << uint16(0)
		<< gameid
		<< status
		<< result
		<< data1
		<< data2;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateRouletteTOPPacket(WorldPacket * packet, TownPtr & pTown)
{
	if (!packet || pTown.isNull())
		return false;

	String szTop = pTown->getStringField("desc");
	std::vector< String > vecString = StringUtil::split(szTop, ",");
	if (vecString.size() < 3)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_SGAMETOP);
	*packet << uint16(SMSG_SGAMETOP) << uint16(0);
	*packet << (uint8)vecString.size();
	uint8 i = 0;
	std::vector<String>::iterator ii, endii = vecString.end();
	for (ii = vecString.begin(); ii != endii; ++ii)
	{
		*packet << ++i;
		AppendPacketString<uint8>(packet, *ii);
	}
	packet->SetLength(packet->size());
	return true;
}

//CMSG_GETUSERCONTACT = 0x0064,		获取玩家联系信息
bool ProtocolsManager::CreateGetUserContactPacket(WorldPacket * packet, CharPtr & pChr, String & strData)
{
	if(!packet || pChr.isNull())
		return false;
	
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(CMSG_GETUSERCONTACT);
	*packet << uint16(CMSG_GETUSERCONTACT) << uint16(0)
			<< uint32(pChr->getHandle());
	
	AppendPacketString<uint16>(packet, strData);
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_SETUSERCONTACT = 0x0065,		设置玩家联系信息
bool ProtocolsManager::CreateSetUserContactPacket(WorldPacket * packet, CharPtr & pChr, String & strData, const uint8 & result)
{
	if(!packet || pChr.isNull())
		return false;
	
	packet->clear();
	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(CMSG_SETUSERCONTACT);
	*packet << uint16(CMSG_SETUSERCONTACT) << uint16(0)
			<< uint32(pChr->getHandle());
	
	AppendPacketString<uint16>(packet, strData);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateVipRoomListPacket(WorldPacket * packet, const uint32 & update_time, const uint16 & offset, const uint16 & num, const uint16 & total_num, std::list<VipRoom> rooms)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VIPROOM_ROOMLIST);
	*packet << uint16(SMSG_VIPROOM_ROOMLIST) << uint16(0);

	*packet << uint32(update_time)
		<< uint16(total_num)
		<< uint16(offset)
		<< uint16(num);

	uint32 packet_offset = packet->size();
	*packet << uint16(rooms.size());

	if (rooms.empty())
	{
		packet->SetLength(packet->size());
		return true;
	}

	uint16 room_num = 0;
	std::list<VipRoom>::iterator iter, ei = rooms.end();
	for (iter = rooms.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).room_id)
			<< uint8((*iter).status)
			<< uint8((*iter).bHaveCodeKey);

		CharPtr pChr = sCharMgr.getByHandle((*iter).landlord_id);
		if (pChr.isNull())
			continue;

		*packet << uint32((*iter).base_coins)
			<< uint32(sXmlDataMgr.GetVipRoomBaseCoins((*iter).base_coins))
			<< uint8((*iter).normal_players.size());

		for (uint8 i = 0; i < (*iter).normal_players.size(); ++i)
		{
			uint32 char_id = (*iter).normal_players[i]._handle;
			*packet << uint32(char_id)
				<< uint8((*iter).players_status[i]);

			if (!char_id)
			{
				*packet << uint8(0)
					<< uint8(0)
					<< uint32(0)
					<< uint8(0)
					<< uint8(0)
					<< uint8(0);
			}
			else
			{
				CharPtr chr = sCharMgr.getByHandle(char_id);
				if (!chr.isNull())
				{
					AppendPacketString<uint8>(packet, chr->getCharName());
					AppendPacketString<uint8>(packet, chr->getStringField("desc"));

					uint32 coins = sGLMgr.GetItemNum(chr, ItemModel_Coins);

					*packet << uint32(coins)
						<< uint8(chr->getUInt32Field("lv"))
						<< uint8(chr->getUInt32Field("rank"));

					sVipCardMgr.PacketVipIcon(packet, chr);
				}
				else
				{
					*packet << uint8(0)
						<< uint8(0)
						<< uint32(0)
						<< uint8(0)
						<< uint8(0)
						<< uint8(0);
				}
			}
		}

		++room_num;
	}

	if (room_num != rooms.size())
		packet->SetOffset(packet_offset, room_num);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateVipRoomInfoPacket(WorldPacket * packet, VipRoom vipRoom, const uint8 & nExist)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VIPROOM_ROOMINFO);
	*packet << uint16(SMSG_VIPROOM_ROOMINFO) << uint16(0)
		<< uint32(vipRoom.room_id)
		<< uint8(vipRoom.status);

	CharPtr pChr = sCharMgr.getByHandle(vipRoom.landlord_id);
	if (pChr.isNull())
		return false;

	AppendPacketString<uint8>(packet, vipRoom.strCode);

	*packet << uint32(vipRoom.base_coins)
		<< uint32(sXmlDataMgr.GetVipRoomBaseCoins(vipRoom.base_coins))
		<< uint8(vipRoom.normal_players.size());

	for (uint8 i = 0; i < vipRoom.normal_players.size(); ++i)
	{
		uint32 char_id = vipRoom.normal_players[i]._handle;
		*packet << uint32(char_id)
			<< uint8(vipRoom.players_status[i]);

		if (!char_id)
		{
			*packet << uint8(0)
				<< uint8(0)
				<< uint32(0)
				<< uint8(0)
				<< uint8(0)
				<< uint8(0);
		}
		else
		{
			CharPtr chr = sCharMgr.getByHandle(char_id);
			if (!chr.isNull())
			{
				AppendPacketString<uint8>(packet, chr->getCharName());
				AppendPacketString<uint8>(packet, chr->getStringField("desc"));

				uint32 coins = sGLMgr.GetItemNum(chr, ItemModel_Coins);
				*packet << uint32(coins)
					<< uint8(chr->getUInt32Field("lv"))
					<< uint8(chr->getUInt32Field("rank"));

				sVipCardMgr.PacketVipIcon(packet, chr);
			}
			else
			{
				*packet << uint8(0)
					<< uint8(0)
					<< uint32(0)
					<< uint8(0)
					<< uint8(0)
					<< uint8(0);
			}
		}
	}

	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCreateVipRoomPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VIPROOM_CREATE);
	*packet << uint16(SMSG_VIPROOM_CREATE) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateJoinVipRoomPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VIPROOM_JOIN);
	*packet << uint16(SMSG_VIPROOM_JOIN) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateLeaveVipRoomPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_VIPROOM_LEAVE);
	*packet << uint16(SMSG_VIPROOM_LEAVE) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUsedMammonCardPacket(WorldPacket * packet, const uint32 money)
{
	return CreateSimplePacket(packet, SMSG_USEDMAMMONCARD, money);
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateUsedLuckyCardPacket(WorldPacket * packet, const uint32 luckyModelId, const uint32 usedPoint, const float multiple, const uint32 addCoins)
{
	if (!packet)
		return false;
	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_USEDLUCKYCARD);
	*packet << uint16(SMSG_USEDLUCKYCARD) << uint16(0)
		<< luckyModelId
		<< usedPoint
		<< multiple
		<< addCoins;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCheckLeCardResultPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_CHECK_LECARD);
	*packet << uint16(SMSG_CHECK_LECARD) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateGetLeCardsResultPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_CHECK_GETLECARD);
	*packet << uint16(SMSG_CHECK_GETLECARD) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateLeCardsListPacket(WorldPacket * packet, std::list<GameExchange> * exchanges)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_LECARD_LIST);
	*packet << uint16(SMSG_LECARD_LIST) << uint16(0)
		<< uint8(exchanges->size());

	std::list<GameExchange>::iterator iter, ei = exchanges->end();
	for (iter = exchanges->begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).exchange_id);
		AppendPacketString<uint8>(packet, (*iter).token);
		*packet << uint8((*iter).status)
			<< uint32((*iter).data2);
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateLeCardsCoolDownPacket(WorldPacket * packet, const uint32 & timer)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_LECARD_COOLDOWN);
	*packet << uint16(SMSG_LECARD_COOLDOWN) << uint16(0)
		<< uint32(timer);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateLeCardsStatusPacket(WorldPacket * packet, const uint32 & le_id, const uint8 & status)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_LECARD_STATUS);
	*packet << uint16(SMSG_LECARD_STATUS) << uint16(0)
		<< uint32(le_id)
		<< uint32(status);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateUserPublicDataPacket(WorldPacket * packet, const uint32 & data)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_USER_PUBLICDATA);
	*packet << uint16(SMSG_USER_PUBLICDATA) << uint16(0)
		<< uint32(data);

	packet->SetLength(packet->size());
	return true;
}

//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCheckVersionResultPacket(WorldPacket * packet, const GZIDInfo &gzinfo)
{
	if (!packet)
		return false;
	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_CHECKVISION);
	*packet << uint16(SMSG_CHECKVISION) << uint16(0);
	AppendPacketString<uint8>(packet, gzinfo.maxVersion);
	AppendPacketString<uint16>(packet, gzinfo.maxAddr);
	AppendPacketString<uint8>(packet, gzinfo.minVersion);
	*packet << uint32(gzinfo.maxSize);
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool ProtocolsManager::CreateCharSpecificPacket(WorldPacket * packet, const uint32 & char_id, const uint8 & type, const uint32 & data1, const uint32 & data2)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(128);
	packet->SetOpcode(SMSG_SERVER_CHARSPECIFIC);
	*packet << uint16(SMSG_SERVER_CHARSPECIFIC) << uint16(0)
		<< uint32(char_id)
		<< uint8(type)
		<< uint32(data1)
		<< uint32(data2);

	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool ProtocolsManager::CreateUsePropPacket(WorldPacket * packet, const uint32 & serial, const uint32 & propid, const uint8 & result)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_USETABLE_PORP);
	*packet << uint16(SMSG_USETABLE_PORP) << uint16(0);
	*packet << serial << propid << result;
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool ProtocolsManager::CreateBodyListPacket(WorldPacket * packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;
	using namespace AIScript;
	AICreatureBaseInterface *pAIChrBaseInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if (pAIChrBaseInfe == NULL)
		return false;

	std::list<BodyData> lstBody;
	if (!pAIChrBaseInfe->GetCreatureBodyList(lstBody))
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_BODY_LIST);
	*packet << uint16(SMSG_BODY_LIST) << uint16(0);
	*packet << uint16(pChr->getUInt32Field("id"));
	*packet << (uint8)lstBody.size();
	std::list<BodyData>::iterator iter, enditer = lstBody.end();
	for (iter = lstBody.begin(); iter != enditer; ++iter)
	{
		*packet << (uint16)(*iter).id;
		*packet << (uint32)(*iter).endtime;
	}
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//----------------------------------------------------------------
bool 	ProtocolsManager::CreateGraphicsPacket(WorldPacket* packet, const uint8 & type, const uint32 & data1, const uint32 & data2)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_SHARD_GRAPHIC);
	*packet << uint16(SMSG_SHARD_GRAPHIC) << uint16(0);
	*packet << type << (uint32)data1 << (uint32)data2;

	packet->SetLength(packet->size());
	return true;
}

//----------------------------------------------------------------
bool ProtocolsManager::CreateOperatorPropPacket(WorldPacket * packet, const uint8 & re, const uint32 & src_id,
	const uint32 & propid, const uint32 & target, const uint32 & data1)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_BROW_GRAPHIC);
	*packet << uint16(SMSG_BROW_GRAPHIC) << uint16(0);
	*packet << re << src_id << propid << target << data1;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateLoginServerPacket(WorldPacket* packet, const GameServer & server, bool isAssert)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_REQUEST_LOGINSERVER);
	*packet << uint16(SMSG_REQUEST_LOGINSERVER) << uint16(0);
	*packet << uint16(server.server_id);
	*packet << uint16(server.gz_id);
	AppendPacketString<uint8>(packet, server.server_ip);
	*packet << uint32(server.port);
	*packet << (uint8)isAssert;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateChangeLinkServerPacket(WorldPacket* packet, const uint16 &active, const uint8 &result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CHANGELINK_REQUEST);
	*packet << uint16(SMSG_CHANGELINK_REQUEST) << uint16(0);
	*packet << active << result;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateUserExchangePacket(WorldPacket* packet, uint8 result, std::map<uint16, uint32> &mapItems)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_EXCHANGE_CDKEY);
	*packet << uint16(SMSG_EXCHANGE_CDKEY) << uint16(0);
	*packet << result << uint8(mapItems.size());
	std::map<uint16, uint32>::iterator iter, enditer = mapItems.end();
	for (iter = mapItems.begin(); iter != enditer; ++iter)
	{
		*packet << uint32(iter->first);
		*packet << uint32(iter->second);
	}
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateUpdateHongBaoPacket(WorldPacket* packet, uint32 hbId, uint8 status, uint32 src_pid, String src_nick, String create_time)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_PROVIDE);
	*packet << uint16(SMSG_HONGBAO_PROVIDE) << uint16(0);
	*packet << hbId << status << src_pid;
	AppendPacketString<uint8>(packet, src_nick);
	AppendPacketString<uint8>(packet, create_time);
	// *packet << create_time;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateGrabHongBaoPacket(WorldPacket* packet, uint32 hbId, uint32 src_pid, String src_nick, String head_url, uint32 getCoinsNum)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_KNOCK);
	*packet << uint16(SMSG_HONGBAO_KNOCK) << uint16(0);
	*packet << (uint32)hbId << (uint32)src_pid;
	AppendPacketString<uint8>(packet, src_nick);
	AppendPacketString<uint8>(packet, head_url);
	*packet << (uint32)getCoinsNum;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateHongBaoHistoryPacket(WorldPacket* packet, std::map<uint32, GamePubData> &mapHistory)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_LIST);
	*packet << uint16(SMSG_HONGBAO_LIST) << uint16(0);
	*packet << uint8(mapHistory.size());
	std::map<uint32, GamePubData>::iterator mapi, endmapi = mapHistory.end();
	for (mapi = mapHistory.begin(); mapi != endmapi; ++mapi)
	{
		GamePubData &gpd = mapi->second;
		*packet << (uint32)gpd.pd_id
			<< (uint32)gpd.src_platform_id;
		AppendPacketString<uint8>(packet, gpd.src_nick);
		AppendPacketString<uint8>(packet, gpd.sdata3);
		*packet << uint32(gpd.ndata2) << uint8(gpd.ndata1);
		AppendPacketString<uint8>(packet, gpd.sdata2);
	}
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateHongBaoRequestPacket(WorldPacket* packet, uint8 surplus)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_REQUEST);
	*packet << uint16(SMSG_HONGBAO_REQUEST) << uint16(0);
	*packet << surplus;
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateHongBaoKnocklistPacket(WorldPacket* packet, const uint32 &hdId, std::list<HongBaoDetail> &lstDetail)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_KNOCKLIST);
	*packet << uint16(SMSG_HONGBAO_KNOCKLIST) << uint16(0);
	*packet << uint32(hdId);
	*packet << uint8(lstDetail.size());
	std::list<HongBaoDetail>::iterator iter, enditer = lstDetail.end();
	for (iter = lstDetail.begin(); iter != enditer; ++iter)
	{
		HongBaoDetail &hbd = *iter;
		*packet << uint32(hbd.pid);
		AppendPacketString<uint8>(packet, hbd.nick);
		AppendPacketString<uint8>(packet, hbd.head_url);
		*packet << uint32(hbd.hbNum);
	}
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateHongBaoTopListPacket(WorldPacket* packet, std::list<HongBaoTop> &lstHBTop)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_TOPLIST);
	*packet << uint16(SMSG_HONGBAO_TOPLIST) << uint16(0);
	*packet << uint8(lstHBTop.size());
	std::list<HongBaoTop>::iterator iter, enditer = lstHBTop.end();
	for (iter = lstHBTop.begin(); iter != enditer; ++iter)
	{
		HongBaoTop &hbt = *iter;
		*packet << uint32(hbt.pid);
		AppendPacketString<uint8>(packet, hbt.nick);
		AppendPacketString<uint8>(packet, hbt.head_url);
		*packet << uint32(hbt.hbNum);
	}
	packet->SetLength(packet->size());
	return true;
}
//----------------------------------------------------------------
bool 	ProtocolsManager::CreateHongBaoCanGrabListPacket(WorldPacket* packet, std::map<uint32, GamePubData> &mapHBList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_HONGBAO_CANKNOCKLIST);
	*packet << uint16(SMSG_HONGBAO_CANKNOCKLIST) << uint16(0);
	*packet << uint8(mapHBList.size());
	std::map<uint32, GamePubData>::iterator mapi, endmapi = mapHBList.end();
	for (mapi = mapHBList.begin(); mapi != endmapi; ++mapi)
	{
		GamePubData &gpd = mapi->second;
		*packet << (uint32)gpd.pd_id
			<< (uint32)gpd.src_id;
		AppendPacketString<uint8>(packet, gpd.src_nick);
		AppendPacketString<uint8>(packet, gpd.create_time);
		AppendPacketString<uint8>(packet, gpd.sdata2);
	}
	packet->SetLength(packet->size());
	return true;
}

//=======================================================================================
bool ProtocolsManager::CreateCommonJsonMissionListPacket(WorldPacket* packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;

	packet->clear();
	uint8 packlen = 10;

	// 找不到该任务模式
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	MissionModelPtr missModel = sMissionModelMgr.load(model_id);
	if (missModel.isNull())
		return false;

	std::list<MissionPtr> myMissions;
	pChr->getMissionsList(&myMissions);

	bool bFindMission = false;
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it = myMissions.begin(); it != myMissions.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pMission = *it;
			bFindMission = true;
			break;
		}
	}

	if (!bFindMission)
		return false;

	packet->SetOpcode(SMSG_JSON_MISSION_LIST);
	*packet << uint16(SMSG_JSON_MISSION_LIST) << uint16(packlen);

	Json::Value val;
	Json::Reader reader;
	reader.parse(pMission->getStringField("require"), val);

	*packet << uint8(val.size());

	for (Json::Value::iterator iter = val.begin(); iter != val.end(); ++iter)
	{
		char strMissionType[256] = "";
		if (iter.key().asString() == "daily_missions")
		{
			sprintf(strMissionType, "%s", "daily_missions");
			*packet << uint8(enCommonMissionStyle_Daily);
		}
		else if (iter.key().asString() == "forever_missions")
		{
			sprintf(strMissionType, "%s", "forever_missions");
			*packet << uint8(enCommonMissionStyle_Forever);
		}
		else
		{
			continue;
		}

		uint8 real_mission = 0;
		uint16 offset = packet->size();

		*packet << uint8(val[strMissionType].size());
		for (Json::Value::iterator iter = val[strMissionType].begin(); iter != val[strMissionType].end(); ++iter)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iter.key().asString());
			MissionModelPtr model = sMissionModelMgr.load(missionModelID);
			if (model.isNull())
				continue;

			*packet << uint32(missionModelID)					//任务模式ID
				<< uint8((*iter)["s"].asUInt())				//任务状态
				<< uint32((*iter)["n"].asUInt())			//当前任务完成进度
				<< uint32(model->getUInt32Field("data1"))	//任务完成上限
				<< uint32(model->getUInt32Field("data2"))	//任务奖励铜钱
				<< uint32((*iter)["ft"].asUInt());			//任务完成时间

			AppendPacketString<uint8>(packet, (*iter)["name"].asString());
			AppendPacketString<uint8>(packet, (*iter)["desc"].asString());
			++real_mission;
		}

		packet->SetOffset(offset, real_mission);
	}

	packet->SetLength(packet->size());
	return true;
}

//=======================================================================================
bool ProtocolsManager::CreateCommonSingleJsonMissionPacket(WorldPacket * packet,
	const uint32 & model_id,
	const uint8 & status,
	const uint32 & curr_count,
	const uint32 & max_count)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_SINGLE_JSON_MISSION);
	*packet << uint16(SMSG_SINGLE_JSON_MISSION) << uint16(0)
		<< uint32(model_id)
		<< uint8(status)
		<< uint32(curr_count)
		<< uint32(max_count);

	packet->SetLength(packet->size());
	return true;
}

//=======================================================================================
bool ProtocolsManager::CreateGetJsonMissionBountyPacket(WorldPacket * packet, const uint32 & model_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_GET_JSON_MISSION_GETBOUNTY);
	*packet << uint16(SMSG_GET_JSON_MISSION_GETBOUNTY) << uint16(0)
		<< uint32(model_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//==========================================================================
bool ProtocolsManager::CreateCommonJsonEffectListPacket(WorldPacket* packet, CharPtr & pChr)
{
	if (!packet || pChr.isNull())
		return false;

	packet->clear();
	uint8 packlen = 10;

	packet->SetOpcode(SMSG_JSON_EFFORT_LIST);
	*packet << uint16(SMSG_JSON_EFFORT_LIST) << uint16(packlen);

	std::list<EffectPtr> effects;
	pChr->getEffectsList(&effects);

	if (effects.empty())
		return false;

	EffectPtr pEffect = *effects.begin();

	Json::Value val;
	Json::Reader reader;
	reader.parse(pEffect->getStringField("info"), val);

	uint8 offset = packet->size();
	uint8 real_effect = 0;
	uint8 effect_num = val.size();
	*packet << uint8(effect_num);

	for (Json::Value::iterator iter = val.begin(); iter != val.end(); ++iter)
	{
		uint32 effectModelID = (*iter)["model_id"].asUInt();
		EffectModelPtr model = sEffectModelMgr.load(effectModelID);
		if (model.isNull())
			continue;

		*packet << uint32(effectModelID)						//成就模式ID
				<< uint8((*iter)["status"].asUInt())			//成就状态
				<< uint32((*iter)["complate_count"].asUInt())	//当前成就完成进度
				<< uint32((*iter)["need_count"].asUInt())		//成就完成上限
				<< uint32((*iter)["bounty_num"].asUInt())		//成就奖励铜钱
				<< uint32((*iter)["finish_time"].asUInt());		//成就完成时间
		
		AppendPacketString<uint8>(packet, (*iter)["name"].asString());
		AppendPacketString<uint8>(packet, (*iter)["desc"].asString());
		++real_effect;
	}

	packet->SetOffset(offset, real_effect);
	packet->SetLength(packet->size());
	return true;
}

//==========================================================================
bool ProtocolsManager::CreateCommonSingleJsonEffectPacket(WorldPacket * packet,
	const uint32 & model_id,
	const uint8 & status,
	const uint32 & curr_count,
	const uint32 & max_count)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_JSON_SINGLEEFFORT_INFO);
	*packet << uint16(SMSG_JSON_SINGLEEFFORT_INFO) << uint16(0)
		<< uint32(model_id)
		<< uint8(status)
		<< uint32(curr_count)
		<< uint32(max_count);

	packet->SetLength(packet->size());
	return true;
}

//==========================================================================
bool ProtocolsManager::CreateGetJsonEffectBountyPacket(WorldPacket * packet, const uint32 & model_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_GET_JSON_EFFORT_GETBOUNTY);
	*packet << uint16(SMSG_GET_JSON_EFFORT_GETBOUNTY) << uint16(0)
		<< uint32(model_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//==========================================================================
bool ProtocolsManager::CreateCommonTopQueuePacket(WorldPacket * packet, const uint8 type, std::list<stCommonQueueTop> &lstQT)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_COMMON_ORDERLIST);
	*packet << uint16(SMSG_COMMON_ORDERLIST) << uint16(0)
		<< uint8(type)
		<< uint8(lstQT.size());

	std::list<stCommonQueueTop>::iterator iter = lstQT.begin(), iterEnd = lstQT.end();
	for (; iter != iterEnd; ++iter)
	{
		*packet << uint32((*iter).id);
		Json::Value val;
		val["name"] = (*iter).name;
		val["pid"] = (*iter).pid;
		val["sign_name"] = (*iter).sign_name;
		
		Json::FastWriter w;
		AppendPacketString<uint16>(packet, w.write(val));

		AppendPacketString<uint8>(packet, (*iter).head);
		*packet << uint32((*iter).data);
	}
	// 设置包真正的长度
	packet->SetLength(packet->size());
	return true;
}

//==========================================================================
bool ProtocolsManager::CreateCommonTopQueueNewPacket(WorldPacket * packet, const uint8 type, std::list<stCommonQueueTop> &lstQT, const uint8 & offset, const uint8 & num)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_COMMON_ORDERLISTNEW);
	*packet << uint16(SMSG_COMMON_ORDERLISTNEW) << uint16(0)
			<< uint8(type)
			<< uint8(lstQT.size())
			<< uint8(offset);
	
	uint8 real_num = 0;
	uint32 packet_offset = packet->size();
	*packet << uint8(num);
	
	uint8 index = 0;
	std::list<stCommonQueueTop>::iterator iter = lstQT.begin(), iterEnd = lstQT.end();
	for (; iter != iterEnd; ++iter)
	{
		++index;
		if(index < offset + 1)
			continue;
		
		*packet << uint32((*iter).id)
				<< uint32((*iter).pid);
		
		// String name = string_url_encode((*iter).name);
		String name = Base64Encode((*iter).name.c_str(), (*iter).name.size());
		AppendPacketString<uint8>(packet, name);
		
		Json::Value val;
		Json::Reader reader;
		reader.parse((*iter).sign_name, val);
		
		String sign_name = "";
		
		if(val.isMember("簽名"))
		{
			sign_name = Base64Encode(val["簽名"].asString().c_str(), val["簽名"].asString().size());
		}
		else if(val.isMember("签名"))
		{
			sign_name = Base64Encode(val["签名"].asString().c_str(), val["签名"].asString().size());
		}
		
		AppendPacketString<uint16>(packet, sign_name);
		AppendPacketString<uint8>(packet, (*iter).head);
		AppendPacketString<uint8>(packet, (*iter).addr);
		*packet << uint8((*iter).sex)
				<< uint32((*iter).data);
		
		++real_num;
		if(real_num >= num)
			break;
	}
	
	packet->SetOffset(packet_offset, real_num);
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreatePubBankDataPacket(WorldPacket * packet, GameBank bank, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_GETPLAYERINFO_BYPID);
	*packet << uint16(SMSG_GETPLAYERINFO_BYPID) << uint16(0);

	String strNick = "";
	if (bank.bank_id != 0)
		strNick = bank.nick;

	AppendPacketString<uint8>(packet, strNick);	// 玩家昵称
	*packet << uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateUpdateCenterPlatformFriendPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_UPDATE_PLATFRIENDS);
	*packet << uint16(SMSG_CENTER_UPDATE_PLATFRIENDS) << uint16(0)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterFriendListPacket(WorldPacket * packet, const uint8 & type, std::list<CenterGameFriend> lstFriend)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_FRIENDLIST_INFO);
	*packet << uint16(SMSG_CENTER_FRIENDLIST_INFO) << uint16(0)
		<< uint8(type)
		<< uint16(lstFriend.size());

	std::list<CenterGameFriend>::iterator iter, ei = lstFriend.end();
	for (iter = lstFriend.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).friend_id)	// 游戏好友ID
			<< uint8((*iter).type)				// 好友类型
			<< uint8((*iter).flag)				// 好友标志
			<< uint8((*iter).status)			// 好友状态
			<< uint32((*iter).category)			// 好友分组
			<< uint32((*iter).create_gz_id)		// 创建好友关系时的分区ID
			<< uint32((*iter).friend_user_pid)	// 好友PID
			<< uint32((*iter).create_time)		// 创建时间
			<< uint32((*iter).ll_time);			// 最后登陆时间

		AppendPacketString<uint8>(packet, (*iter).name);			//好友名称
		AppendPacketString<uint8>(packet, (*iter).nick);			//好友昵称
		AppendPacketString<uint8>(packet, (*iter).desc);			//好友头像地址
		AppendPacketString<uint16>(packet, (*iter).user_data);	//好友数据信息
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterSystemFriendListPacket(WorldPacket * packet, std::list<ResourcePtr> lstFriend)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_SYSTEMFRIENDS);
	*packet << uint16(SMSG_CENTER_SYSTEMFRIENDS) << uint16(0)
		<< uint8(lstFriend.size());

	std::list<ResourcePtr>::iterator iter, ei = lstFriend.end();
	for (iter = lstFriend.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter)->getUInt32Field("platform_id"));				// 玩家PID
		AppendPacketString<uint8>(packet, (*iter)->getStringField("nick"));		// 好友名称

		String strIcon = "";
		CharPtr pChr = sCharMgr.load((*iter)->getUInt32Field("char_id"));
		if (!pChr.isNull())
			strIcon = pChr->getStringField("desc");

		AppendPacketString<uint8>(packet, strIcon);								// 好友头像地址
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterFriendInfoPacket(WorldPacket * packet, CenterGameFriend cFriend, const uint8 & mode)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_FRIEND_INFO);
	*packet << uint16(SMSG_CENTER_FRIEND_INFO) << uint16(0)
		<< uint32(cFriend.friend_id)		// 游戏好友ID
		<< uint8(cFriend.type)				// 好友类型
		<< uint8(cFriend.flag)				// 好友标志
		<< uint8(cFriend.status)			// 好友状态
		<< uint32(cFriend.category)			// 好友分组
		<< uint32(cFriend.create_gz_id)		// 创建好友关系时的分区ID
		<< uint32(cFriend.friend_user_pid)	// 好友PID
		<< uint32(cFriend.create_time)		// 创建时间
		<< uint32(cFriend.ll_time);			// 最后登陆时间

	AppendPacketString<uint8>(packet, cFriend.name);			//好友名称
	AppendPacketString<uint8>(packet, cFriend.nick);			//好友昵称
	AppendPacketString<uint8>(packet, cFriend.desc);			//好友头像地址
	AppendPacketString<uint16>(packet, cFriend.user_data);	//好友数据信息

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterOperatorFriendPacket(WorldPacket * packet, const uint32 & destCharID, const uint8 & mode, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_OPERATOR_FRIEND);
	*packet << uint16(SMSG_CENTER_OPERATOR_FRIEND) << uint16(0)
		<< uint32(destCharID)
		<< uint8(mode)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCommitCenterPlayerInfoPacket(WorldPacket * packet, const uint8 & type, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_COMMITPLAYERINFO);
	*packet << uint16(SMSG_CENTER_COMMITPLAYERINFO) << uint16(0)
		<< uint8(type)
		<< uint8(result);

	packet->size();
	return true;
}

bool ProtocolsManager::CreateCenterPlayerInfoListPacket(WorldPacket * packet, const uint32 & pid, const uint32 & gz_id, std::list<CenterFriendRecord> lstData)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_PLAYERINFO);
	*packet << uint16(SMSG_CENTER_PLAYERINFO) << uint16(0)
		<< uint32(pid)
		<< uint32(gz_id)
		<< uint8(lstData.size());

	std::list<CenterFriendRecord>::iterator iter, ei = lstData.end();
	for (iter = lstData.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).record_id)						//记录ID
			<< uint8((*iter).status)								//状态
			<< uint32((*iter).pid)									//用户PID
			<< uint32((*iter).gz_id)								//数据分区ID
			<< uint8((*iter).data1)									//游戏玩法
			<< uint32((*iter).lu_timer);							//数据最后一次更新时间
		
		AppendPacketString<uint16>(packet, (*iter).record_data);	//记录数据字符串
	}

	packet->size();
	return true;
}

bool ProtocolsManager::CreateCenterPlayerCountInfoPacket(WorldPacket * packet, const uint32 & pid, std::vector<stGzidSampleCountInfo> lstData)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_PLAYERCOUNTINFO);
	*packet << uint16(SMSG_CENTER_PLAYERCOUNTINFO) << uint16(0)
			<< uint32(pid)
			<< uint8(lstData.size());
	
	std::vector<stGzidSampleCountInfo>::iterator iter, ei=lstData.end();
	for(iter = lstData.begin(); iter!=ei; ++iter)
	{
		*packet << uint16((*iter).gz_id)
				<< uint16((*iter).mode)
				<< uint32((*iter).zcs)
				<< uint32((*iter).slcs);
	}
	
	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterFriendCategoryListPacket(WorldPacket * packet, std::list<CenterFriendCategory> lCate)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_FRIENDCATEGORYLIST);
	*packet << uint16(SMSG_CENTER_FRIENDCATEGORYLIST) << uint16(0)
		<< uint8(lCate.size());

	std::list<CenterFriendCategory>::iterator iter, ei = lCate.end();
	for (iter = lCate.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).cate_id)					//分组ID
			<< uint8((*iter).flag);						//分组类型（系统，平台，自定义）

		AppendPacketString<uint8>(packet, (*iter).name);	//分组名称
	}

	packet->SetLength(packet->size());
	return true;
}


bool CreateCenterFriendCategoryOperatorResultPacket(WorldPacket * packet, const uint8 & mode, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_FRIENDCATEGORY_OP);
	*packet << uint16(SMSG_CENTER_FRIENDCATEGORY_OP) << uint16(0)
		<< uint8(mode)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateRequireCenterBattleResultPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATLLE_REQUIRECREATE);
	*packet << uint16(SMSG_CENTER_BATLLE_REQUIRECREATE) << uint16(0)
			<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterBattleListPacket(WorldPacket * packet, std::list<CenterBattle> lcb)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_LIST);
	*packet << uint16(SMSG_CENTER_BATTLE_LIST) << uint16(0)
		<< uint8(lcb.size());

	uint32 num = 0;
	using namespace AIScript;
	std::list<CenterBattle>::iterator iter, ei = lcb.end();
	for (iter = lcb.begin(); iter != ei; ++iter)
	{
		// 查询在牌桌中的玩家数据
		/* std::list<CenterBattleUser> lstData;
		GetCenterBattleUserList(&lstData, "(status = %u or status = %u) and cb_id = %u",
					enCenterBattlePlayerStatus_Free, enCenterBattlePlayerStatus_Playing,(*iter).cb_id); */

		Json::Reader reader;
		Json::Value val;
		reader.parse((*iter).player, val);
		
		*packet << uint32((*iter).cb_id)				// 组局ID
			<< uint8((*iter).status)					// 状态
			<< uint32((*iter).gz_id)					// 分区ID
			<< uint32((*iter).game_id)					// 游戏ID
			<< uint8((*iter).mode)						// 游戏模式
			<< uint32((*iter).base_coins)				// 底分
			<< uint32((*iter).fan_coins)				// 翻分
			<< uint8((*iter).istrack)					// 是否可追踪（0 否 1 是）
			<< uint32((*iter).curr_loop)				// 当前局数
			<< uint32((*iter).limit_loop)				// 限制局数
			<< uint32((*iter).limit_time)				// 限制时间
			<< uint32((*iter).top_times)				// 封顶翻数倍数
			<< uint32((*iter).coins_model)				// 游戏货币类型
			<< uint32((*iter).init_coins)				// 初始带入货币数量
			<< uint32((*iter).think_time)				// 考虑时间
			<< uint32((*iter).timeout)					// 超时时间
			<< uint32(time(0) - (*iter).start_time)		// 游戏时间
			<< uint32((*iter).update_key)				// 更新key
			<< uint32((*iter).pid);						// 房主PID

		AppendPacketString<uint8>(packet, (*iter).name);			// 房主名称
		AppendPacketString<uint8>(packet, string_url_decode((*iter).battle_name));		// 房间名称
		AppendPacketString<uint16>(packet, (*iter).sdata2);			// 玩法设定

		*packet << uint32((*iter).channel_id);						// 牌桌ID
		AppendPacketString<uint8>(packet, (*iter).join_code);		// 验证码

		*packet << uint8((*iter).pause)			// 暂停状态
			<< uint16((*iter).max_player)	// 最大玩家属
			// << uint16(lstData.size());
			<< uint16(val.size());			// 玩家数量

	/* std::list<CenterBattleUser>::iterator itP, eiP = lstData.end();
	for(itP=lstData.begin(); itP!=eiP; ++itP)
	{
		*packet << uint32((*itP).char_id)				// 角色ID
				<< uint32((*itP).platform_id);			// PID

		AppendPacketString<uint8>(packet, string_url_decode((*itP).name));
		AppendPacketString<uint8>(packet, string_url_decode((*itP).head));

		*packet << int32((*itP).curr_score)							// 输赢积分
				<< uint16((*itP).loop)								// 游戏局数
				<< uint8((*itP).status);							// 状态
	} */

		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			uint32 char_id = (*iterVal)["cid"].asUInt();
			*packet << uint32(char_id)						// 角色ID
				<< uint32((*iterVal)["pid"].asUInt());	// PID

			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

			*packet << int32((*iterVal)["winlose"].asInt())					// 输赢积分
				<< uint16((*iterVal)["player_count"].asUInt())			// 游戏局数
				<< uint8((*iterVal)["player_status"].asUInt());			// 状态
		}

		++num;
	}

	if (num != lcb.size())
	{
		packet->SetOffset(4, num);
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterBattleInfoPacket(WorldPacket * packet, CenterBattle cb)
{
	if (!packet)
		return false;

	using namespace AIScript;

	// 查询在牌桌中的玩家数据
	/* std::list<CenterBattleUser> lstData;
	GetCenterBattleUserList(&lstData, "(status = %u or status = %u) and cb_id = %u",
			enCenterBattlePlayerStatus_Free, enCenterBattlePlayerStatus_Playing,cb.cb_id); */

	Json::Reader reader;
	Json::Value val;
	reader.parse(cb.player, val);

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_INFO);
	*packet << uint16(SMSG_CENTER_BATTLE_INFO) << uint16(0)
		<< uint32(cb.cb_id)							// 组局ID
		<< uint8(cb.status)							// 状态
		<< uint32(cb.gz_id)							// 分区ID
		<< uint32(cb.game_id)						// 游戏ID
		<< uint8(cb.mode)							// 游戏模式
		<< uint32(cb.base_coins)					// 底分
		<< uint32(cb.fan_coins)						// 翻分
		<< uint8(cb.istrack)						// 是否可追踪（0 否 1 是）
		<< uint32(cb.curr_loop)						// 当前局数
		<< uint32(cb.limit_loop)					// 限制局数
		<< uint32(cb.limit_time)					// 限制时间
		<< uint32(cb.top_times)						// 限制翻数倍数
		<< uint32(cb.coins_model)					// 游戏货币类型
		<< uint32(cb.init_coins)					// 初始带入货币数量
		<< uint32(cb.think_time)					// 考虑时间
		<< uint32(cb.timeout)						// 超时时间
		<< uint32(time(0) - cb.start_time)			// 游戏时间
		<< uint32(cb.update_key)					// 更新key
		<< uint32(cb.pid);							// 房主PID

	AppendPacketString<uint8>(packet, cb.name);			// 房主名称
	AppendPacketString<uint8>(packet, string_url_decode(cb.battle_name));	// 房间名称
	AppendPacketString<uint16>(packet, cb.sdata2);		// 玩法设定

	*packet << uint32(cb.channel_id);
	AppendPacketString<uint8>(packet, cb.join_code);	//验证码

	*packet << uint8(cb.pause)			// 暂停状态
		<< uint16(cb.max_player)	// 最大玩家数
		// << uint16(lstData.size());
		<< uint16(val.size());	// 玩家数量

/* std::list<CenterBattleUser>::iterator itP, eiP = lstData.end();
for(itP=lstData.begin(); itP!=eiP; ++itP)
{
	*packet << uint32((*itP).char_id)				// 角色ID
			<< uint32((*itP).platform_id);			// PID

	AppendPacketString<uint8>(packet, string_url_decode((*itP).name));
	AppendPacketString<uint8>(packet, string_url_decode((*itP).head));

	*packet << int32((*itP).curr_score)							// 输赢积分
			<< uint16((*itP).loop)								// 游戏局数
			<< uint8((*itP).status);							// 状态
} */

	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		uint32 char_id = (*iterVal)["cid"].asUInt();
		*packet << uint32(char_id)						// 角色ID
			<< uint32((*iterVal)["pid"].asUInt());	// PID

		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

		*packet << int32((*iterVal)["winlose"].asInt())					// 输赢积分
			<< uint16((*iterVal)["player_count"].asUInt())			// 游戏局数
			<< uint8((*iterVal)["player_status"].asUInt());			// 状态
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateGameBattleResultPacket(WorldPacket * packet, const uint32 & cb_id, String join_code, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_GAME_BATTLE_CREATE);
	*packet << uint16(SMSG_GAME_BATTLE_CREATE) << uint16(0)
		<< uint32(cb_id);

	AppendPacketString<uint8>(packet, join_code);

	*packet << uint8(result);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateRemoveCenterBattlePacket(WorldPacket * packet, const uint32 & cb_id)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_REMOCE);
	*packet << uint16(SMSG_CENTER_BATTLE_REMOCE) << uint16(0)
		<< uint32(cb_id);

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterBattleOpPacket(WorldPacket * packet, const uint8 & mode, const uint32 & cb_id, const uint32 & data, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_OPERATOR);
	*packet << uint16(SMSG_CENTER_BATTLE_OPERATOR) << uint16(0)
		<< uint8(mode)
		<< uint32(cb_id)
		<< uint32(data)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 0x00F7 棋牌圈配置信息
bool ProtocolsManager::CreateCenterBattleConfigPacket(WorldPacket * packet, std::map<uint32, std::vector<stCenterBattleOpenCoins> > mapOpenCoins)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_CONFIG);
	*packet << uint16(SMSG_CENTER_BATTLE_CONFIG) << uint16(0)
		<< uint8(mapOpenCoins.size());

	uint32 time_now = time(0);
	std::map<uint32, std::vector<stCenterBattleOpenCoins> >::iterator iter, ei = mapOpenCoins.end();
	for (iter = mapOpenCoins.begin(); iter != ei; ++iter)
	{
		*packet << uint8(iter->first)			// 游戏ID
			<< uint8(iter->second.size());	// 玩法配置数量

		std::vector<stCenterBattleOpenCoins>::iterator itOp, eiOp = iter->second.end();
		for (itOp = iter->second.begin(); itOp != eiOp; ++itOp)
		{
			stCenterBattleOpenCoins stOp = *itOp;
			uint32 model_id = stOp.model_id;
			uint32 num = stOp.num;
			uint32 org_model_id = stOp.model_id;
			uint32 org_num = stOp.num;

			if (time_now >= stOp.free_begin_time && time_now <= stOp.free_end_time)
			{// 免费阶段
				model_id = 0;
				num = 0;
			}

			*packet << uint8(stOp.mode)					// 游戏玩法ID
				<< uint32(org_model_id)				// 原始开局费用模式ID
				<< uint32(org_num)					// 原始开局费用数量
				<< uint32(model_id)					// 开局费模式ID(0表示免费）
				<< uint32(num)						// 开局费数量
				<< uint8(stOp.loop)					// 局数
				<< uint32(stOp.free_begin_time)		// 免费起始时间
				<< uint32(stOp.free_end_time);		// 免费结束时间
		}
	}

	packet->SetLength(packet->size());
	return true;
}

bool ProtocolsManager::CreateCenterBattleKickPlayerPacket(WorldPacket * packet, const uint32 & cb_id, const uint32 & cid, const uint8 & result)
{
	/* if(!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_KICK);
	*packet << uint16(SMSG_CENTER_BATTLE_KICK) << uint16(0)
			<< uint32(cb_id)
			<< uint32(cid)
			<< uint8(result);

	packet->SetLength(packet->size()); */
	return true;
}

bool ProtocolsManager::CreateCenterBattleJoinPacket(WorldPacket * packet, String join_code, const uint32 & gz_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_JOINCHANNEL);
	*packet << uint16(SMSG_CENTER_BATTLE_JOINCHANNEL) << uint16(0);

	AppendPacketString<uint8>(packet, join_code.c_str());

	*packet << uint32(gz_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//0x00F9
bool ProtocolsManager::CreatePlayerCenterBattleLogsPacket(WorldPacket * packet, std::list<CenterBattleLog> logs)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_PLAYER_BATTLELOG);
	*packet << uint16(SMSG_CENTER_PLAYER_BATTLELOG) << uint16(0);

	CenterBattleLog endLog;
	if (logs.size())
		endLog = logs.back();

	*packet << uint32(endLog.cb_id)							// 组局ID
			<< uint32(endLog.data5)							// 房主PID
			<< uint16(endLog.gz_id)							// 分区ID
			<< uint16(endLog.data7);						// 最大轮次
	
	AppendPacketString<uint8>(packet, endLog.sdata1);						// 游戏名称
	AppendPacketString<uint8>(packet, string_url_decode(endLog.sdata2));	// 房间名称
	AppendPacketString<uint8>(packet, endLog.sdata3);						// 房主名称
	AppendPacketString<uint8>(packet, endLog.sdata4);						// 房主头像

	Json::Reader reader;
	Json::Value val, val_real;
	reader.parse(endLog.sdata5, val);

	*packet << uint16(logs.size());									// 记录数量
	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for (iter = logs.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).battle_log_id)					// 中心组局日志ID
				<< uint16((*iter).data3)							// 轮次ID
				<< uint8((*iter).data6);							// 是否有录像
		
		AppendPacketString<uint8>(packet, (*iter).create_time);		// 开始时间

		Json::Value valEx;
		reader.parse((*iter).sdata5, valEx);
		if (valEx.isMember("players"))
		{
			*packet << uint8(valEx["players"].size());

			for (Json::Value::iterator iterVal = valEx["players"].begin(); iterVal != valEx["players"].end(); ++iterVal)
			{
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["pid"] = (*iterVal)["pid"].asUInt();
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["name"] = (*iterVal)["name"].asString();
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["desc"] = (*iterVal)["desc"].asString();
				
				*packet << uint32((*iterVal)["pid"].asUInt());
				*packet << int32((*iterVal)["winlose"].asInt());
				AppendPacketString<uint16>(packet, (*iterVal)["json_data"].asString());
			}
		}
		else
		{
			*packet << uint8(0);
		}
	}

	if (val_real.size())
	{
		*packet << uint8(val_real.size());

		for (Json::Value::iterator iterVal = val_real.begin(); iterVal != val_real.end(); ++iterVal)
		{
			*packet << uint32((*iterVal)["pid"].asUInt());

			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));
		}
	}
	else
	{
		*packet << uint8(0);
	}

	packet->SetLength(packet->size());
	return true;
}

//0x00FA 组局统计信息日志
bool ProtocolsManager::CreateCenterBattleLogPacket(WorldPacket * packet, std::list<CenterBattleLog> logs, const uint32 & cb_id, const uint16 & total_count, const uint16 & offset)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_LOG);
	*packet << uint16(SMSG_CENTER_BATTLE_LOG) << uint16(0)
		<< uint16(total_count)
		<< uint16(offset)
		<< uint16(logs.size());

	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for (iter = logs.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).cb_id)					// 组局ID
			<< uint16((*iter).gz_id)						// 分区ID
			<< uint16((*iter).game_id)						// 游戏ID
			<< uint32((*iter).src_pid)						// 房主PID
			<< uint8((*iter).data12)						// 游戏模式
			<< uint32((*iter).data1)						// 底分
			<< uint32((*iter).data2)						// 翻分
			<< uint16((*iter).data11);						// 封顶倍数翻数

		uint32 use_time = (*iter).data8 > 0 ? (*iter).data8 : time(0) - (*iter).data3;

		*packet << uint32(use_time)							// 用时
			<< uint16((*iter).data4)						// 游戏局数
			<< uint16((*iter).data5)						// 总局数
			<< uint32((*iter).data7)						// 最大赢钱
			<< uint32((*iter).data6);						// 总赢

		AppendPacketString<uint8>(packet, (*iter).sdata1);		// 游戏名称
		AppendPacketString<uint8>(packet, string_url_decode((*iter).sdata2));		// 房间名称
		AppendPacketString<uint8>(packet, (*iter).sdata3);		// 房主名称
		AppendPacketString<uint8>(packet, (*iter).sdata4);		// 房主头像
		AppendPacketString<uint8>(packet, (*iter).sdata7);		// 房间ID
		AppendPacketString<uint8>(packet, (*iter).create_time);	// 开始时间

		Json::Reader reader;
		Json::Value val, val_best;
		reader.parse((*iter).sdata5, val);
		reader.parse((*iter).sdata6, val_best);
		
		// 赢最多玩家昵称，头像
		if (val_best.isMember("win_max"))
		{
			*packet << uint32(val_best["win_max"]["pid"].asUInt());
		}
		else
		{
			*packet << uint32(0);
		}

		// 输最多玩家昵称，头像
		if (val_best.isMember("lose_max"))
		{
			*packet << uint32(val_best["lose_max"]["pid"].asUInt());
		}
		else
		{
			*packet << uint32(0);
		}

		*packet << uint8(val.size());
		Log.Debug("ProtocolsManager::CreateCenterBattleLogPacket","cb_id[%u] val size[%u]", (*iter).cb_id, val.size());
		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			*packet << uint32((*iterVal)["pid"].asUInt());

			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

			*packet << int32((*iterVal)["winlose"].asInt())
					<< uint16((*iterVal)["player_count"].asUInt());
			
			AppendPacketString<uint16>(packet, string_url_decode((*iterVal)["json_data"].asString()));
		}

		// CenterBattle cb;
		// sCenterBattleMgr.GetCenterBattle((*iter).cb_id, &cb);

		// Json::Value valPay;
		// valPay["pay_mode"] = cb.pay_mode;

		// Json::FastWriter w;
		// AppendPacketString<uint16>(packet, w.write(valPay));
	}

	// 返回客户端请求的组局ID（0 表示所有）
	*packet << uint32(cb_id);

	packet->SetLength(packet->size());
	return true;
}

// 0x00FB 创建即时牌局输赢包
bool ProtocolsManager::CreateCurrentCenterBattleWinLosePacket(WorldPacket * packet, CenterBattleLog log)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_CURRWINLOSE);
	*packet << uint16(SMSG_CENTER_BATTLE_CURRWINLOSE) << uint16(0);

	Json::Reader reader;
	Json::Value val;
	reader.parse(log.sdata5, val);

	*packet << uint8(val.size());
	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		*packet << uint32(StringConverter::parseUnsignedInt(iterVal.key().asString()));

		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

		*packet << int32((*iterVal)["winlose"].asInt())
			<< uint32((*iterVal)["player_count"].asUInt());
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建即时牌局输赢包
bool ProtocolsManager::CreateCurrentCenterBattleWinLosePacket(WorldPacket * packet, CenterBattle cb)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_CURRWINLOSE);
	*packet << uint16(SMSG_CENTER_BATTLE_CURRWINLOSE) << uint16(0);

	Json::Reader reader;
	Json::Value val;
	reader.parse(cb.player, val);

	*packet << uint8(val.size());
	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		*packet << uint32(StringConverter::parseUnsignedInt(iterVal.key().asString()));

		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
		AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

		*packet << int32((*iterVal)["winlose"].asInt())
			<< uint32((*iterVal)["player_count"].asUInt());
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建组局单轮记录数据
bool ProtocolsManager::CreateCenterBattleSingleLoopLogPacket(WorldPacket * packet, const uint32 & cb_id, const uint8 & loop, CenterBattleLog log)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_BATTLE_SINGLELOOPLOG);
	*packet << uint16(SMSG_CENTER_BATTLE_SINGLELOOPLOG) << uint16(0);

	if (log.cb_id != 0)
	{
		*packet << uint32(log.cb_id)
				<< uint8(log.data3);
		
		AppendPacketString<uint16>(packet, log.sdata5);
		AppendPacketString<uint8>(packet, log.create_time);
	}
	else
	{
		*packet << uint32(cb_id)
				<< uint8(loop)
				<< uint16(0)
				<< uint8(0);
	}

	packet->SetLength(packet->size());
	return true;
}

// 中秋活动
bool ProtocolsManager::CreateZhongQiuActivityPacket(WorldPacket * packet, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_ZHONGQIU_ACTIVITY);
	*packet << uint16(SMSG_ZHONGQIU_ACTIVITY) << uint16(5)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 通知在线奖励 0x001B
bool ProtocolsManager::CreateNoticeCommonOnlineGiftPacket(WorldPacket * packet, String & strVal)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_ONLINE_BONUS);
	*packet << uint16(SMSG_ONLINE_BONUS) << uint16(5);

	Json::Reader reader;
	Json::Value val;
	reader.parse(strVal, val);

	Log.Debug("CreateNoticeCommonOnlineGiftPacket", "size[%u]", val.size());
	*packet << uint8(val.size());	// 在线礼包数量
	if (val.size())
	{
		for (Json::Value::iterator it = val.begin(); it != val.end(); ++it)
		{
			uint32 left_time = 0;
			if ((*it)["status"].asUInt() == enOnlineGiftStatus_Process)
			{
				left_time = (*it)["need_seconds"].asUInt() - (*it)["curr_seconds"].asUInt();
			}

			*packet << uint8((*it)["id"].asUInt())				// 礼包ID
				<< uint32((*it)["coins"].asUInt())			// 铜钱
				<< uint32((*it)["need_seconds"].asUInt())	// 需要总在线时间
				<< uint32(left_time)						// 剩余时间
				<< uint8((*it)["status"].asUInt());			// 礼包状态

			Log.Debug("CreateNoticeCommonOnlineGiftPacket", "id[%u] coins[%u] need_seconds[%u]",
				(*it)["id"].asUInt(), (*it)["coins"].asUInt(), (*it)["need_seconds"].asUInt());
		}
	}

	packet->SetLength(packet->size());
	return true;
}

// 领取通用在线奖励 0x001C
bool ProtocolsManager::CreateGetCommonOnlineGiftResultePacket(WorldPacket * packet, const uint32 & id, const uint32 & coins, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_GETONLINE_BONUS);
	*packet << uint16(SMSG_GETONLINE_BONUS) << uint16(5)
		<< uint8(id)
		<< uint32(coins)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 转发字符串数据
bool ProtocolsManager::CreateHandleStringPacket(WorldPacket * packet, const uint8 & type, const uint32 & extra_data, String & strData)
{
	if (!packet)
		return false;

	packet->clear();

	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_HANDLE_STRING);
	*packet << uint16(SMSG_HANDLE_STRING) << uint16(0)
		<< uint8(type)
		<< uint32(extra_data);

	AppendPacketString<uint16>(packet, strData);

	packet->SetLength(packet->size());
	return true;
}

// 踢人提示协议
bool ProtocolsManager::CreateKickeOutNoticePacket(WorldPacket * packet, uint32 char_id, uint8 why)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_CENTER_KICKEDOUTNOTICE);
	*packet << uint16(SMSG_CENTER_KICKEDOUTNOTICE) << uint16(0)
		<< uint32(char_id)
		<< uint8(why);

	packet->SetLength(packet->size());
	return true;
}

// 游戏录像
bool ProtocolsManager::CreateGameRecordVedio(WorldPacket * packet, const uint32 & cb_id, const uint8 & loop_id, String record_data, const uint8 & mode)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_GAMERECORD_VEDIO);
	*packet << uint16(SMSG_GAMERECORD_VEDIO) << uint16(0)
		<< uint32(cb_id)
		<< uint8(loop_id);

	AppendPacketString<uint16>(packet, record_data);

	*packet << uint8(mode);
	packet->SetLength(packet->size());
	return true;
}

// 赠送道具结果
bool ProtocolsManager::CreateGiveItemResultPacket(WorldPacket * packet, const uint32 & recv_pid, const uint32 & model_id, const uint32 & num, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSG_SENDITEMTOUSER);
	*packet << uint16(SMSG_SENDITEMTOUSER) << uint16(0)
		<< uint32(recv_pid)
		<< uint32(model_id)
		<< uint32(num)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 获取赠送获赠道具记录 0x0031
bool ProtocolsManager::CreateGiveRecvItemLogsPacket(WorldPacket * packet, const uint32 & platform_id)
{
	packet->clear();
	packet->SetOpcode(SMSG_SENDRECVITEM_LOGS);
	*packet << uint16(SMSG_SENDRECVITEM_LOGS) << uint16(0);
	std::list<GameLog> lstGameLogs;
	char strSql[512] = "";
	sprintf(strSql, "UNIX_TIMESTAMP(create_time) >= %u AND `src_id` = %u AND `type` = %u order by `create_time` DESC",
		uint32(time(0) - sXmlDataMgr.GetConfXMLValue("HF_RECODE_TIME")), platform_id, en_Operate_GiveItem);

	sChannelMgr.getRawCenterLogList(&lstGameLogs, 0, sXmlDataMgr.GetConfXMLValue("HF_RECODE_COUNT"), strSql);

	*packet << uint8(lstGameLogs.size());
	std::list<GameLog>::iterator iter, enditer = lstGameLogs.end();
	for (iter = lstGameLogs.begin(); iter != enditer; ++iter)
	{
		GameLog &log = *iter;
		*packet << uint8(log.sub_type)							// 日志类型
			<< uint32(log.dest_id);							// 赠送或者获赠玩家PID（买卖没有此项）
		AppendPacketString<uint8>(packet, log.sdata1);			// 赠送或者获赠玩家昵称（买卖没有此项）
		*packet << uint32(log.data1);							// 道具模式ID
		*packet << uint32(log.data2);							// 道具数量
		AppendPacketString<uint8>(packet, log.create_time);		// 日志创建时间
	}

	packet->SetLength(packet->size());
	return true;
}

// 评价总体信息0x00E1
bool ProtocolsManager::CreateJudgeTotalInfoPakcet(WorldPacket * packet,
	const uint32 & pid,
	const uint32 & total_judge_count,
	const uint32 & total_star,
	double star_level,
	const uint32 & start_game_count,
	const uint32 & play_game_count,
	float win_percent,
	const uint32 & total_win,
	float aver_winScore,
	String effect_label)
{
	packet->clear();
	packet->SetOpcode(SMSG_JUDGE_TOTALINFO);
	*packet << uint16(SMSG_JUDGE_TOTALINFO) << uint16(0)
		<< uint32(pid)
		<< uint32(total_judge_count)
		<< uint32(total_star)
		<< Real(star_level)
		<< uint32(start_game_count)
		<< uint32(play_game_count)
		<< Real(win_percent)
		<< uint32(total_win)
		<< Real(aver_winScore);

	Json::Value val;
	Json::Reader reader;
	reader.parse(effect_label, val);

	uint8 packet_offset = packet->size();
	uint8 label_size = 0;
	*packet << uint8(val.size());
	if (val.size())
	{
		for (Json::Value::iterator iterV = val.begin(); iterV != val.end(); ++iterV)
		{
			if ((*iterV).asUInt() == 0)
				continue;

			uint32 label_id = StringConverter::parseUnsignedInt(iterV.key().asString());

			*packet << uint8(label_id)
				<< uint32((*iterV).asUInt());

			AppendPacketString<uint8>(packet, sXmlDataMgr.GetJudgeLabelNameByID(label_id));

			++label_size;
		}
	}

	packet->SetOffset(packet_offset, label_size);
	packet->SetLength(packet->size());
	return true;
}

// 评价玩家结果0x00E2
bool ProtocolsManager::CreateJudgePlayerResultPacket(WorldPacket * packet,
	const uint32 & target_id,
	const uint32 & target_type,
	const uint32 & pid,
	const uint32 & judge_pid,
	const uint8 & level,
	std::vector<uint8> vLabel,
	String judge_info,
	const uint8 & result)
{
	packet->clear();
	packet->SetOpcode(SMSG_JUDGE_JUDGEPLAYER);
	*packet << uint16(SMSG_JUDGE_JUDGEPLAYER) << uint16(0)
		<< uint32(target_id)
		<< uint32(target_type)
		<< uint32(pid)
		<< uint32(judge_pid)
		<< uint8(level)
		<< uint8(vLabel.size());

	std::vector<uint8>::iterator iter, ei = vLabel.end();
	for (iter = vLabel.begin(); iter != ei; ++iter)
	{
		*packet << uint8(*iter);
	}

	AppendPacketString<uint8>(packet, judge_info);
	*packet << uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 评价信息列表0x00E3
bool ProtocolsManager::CreateJudgeInfoListPacket(WorldPacket * packet,
	const uint32 & pid,
	const uint32 & offset,
	const uint8 & num,
	std::list<CenterJudge> cj_list)
{
	packet->clear();
	packet->SetOpcode(SMSG_JUDGE_INFOLIST);
	*packet << uint16(SMSG_JUDGE_INFOLIST) << uint16(0)
		<< uint32(pid)
		<< uint32(offset)
		<< uint8(num)
		<< uint8(cj_list.size());

	std::list<CenterJudge>::iterator iter, ei = cj_list.end();
	for (iter = cj_list.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).judge_id)		// 评价ID
			<< uint32((*iter).judge_pid);	// 评价人PID

		AppendPacketString<uint8>(packet, (*iter).judge_nickname);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).judge_icon_url);	// 头像

		*packet << uint8((*iter).judge_level)	// 评价星级
			<< uint8((*iter).label_id);		// 标签ID

		AppendPacketString<uint8>(packet, sXmlDataMgr.GetJudgeLabelNameByID((*iter).label_id));	// 标签名称
		AppendPacketString<uint8>(packet, (*iter).judge_info);	// 评价内容

		*packet << uint32((*iter).create_time)					// 评价时间
			<< Real((*iter).coord_latitude)					// 纬度
			<< Real((*iter).coord_longitude)				// 精度
			<< Real((*iter).coord_altitude);				// 海拔
	}

	packet->SetLength(packet->size());
	return true;
}

// 评价信息确认0x00E4
bool ProtocolsManager::CreateJudgeResultListPacket(WorldPacket * packet, const uint32 & target_id, const uint32 & target_type, std::vector<uint32> vPid)
{
	packet->clear();
	packet->SetOpcode(SMSG_JUDGE_RESULTINFO);
	*packet << uint16(SMSG_JUDGE_RESULTINFO) << uint16(0)
		<< uint32(target_id)
		<< uint32(target_type)
		<< uint8(vPid.size());

	std::vector<uint32>::iterator iter, ei = vPid.end();
	for (iter = vPid.begin(); iter != ei; ++iter)
	{
		*packet << uint32(*iter);
	}

	packet->SetLength(packet->size());
	return true;
}

//=================================棋牌圈牌桌相关协议======================================

// 同IP玩家列表信息 0x00EA
bool ProtocolsManager::CreateCenterBattleSameIpPlayersPacket(WorldPacket * packet, std::map<uint32, std::vector<CharPtr> > mapSameIPChars, const uint8 & wait_timer)
{
	packet->clear();
	packet->SetOpcode(SMSG_CENTERBATTLE_SAMEIPPLAYERS);
	*packet << uint16(SMSG_CENTERBATTLE_SAMEIPPLAYERS) << uint16(0)
		<< uint8(wait_timer)											// 等待时间
		<< uint8(mapSameIPChars.size());								// 同IP玩家类型

	std::map<uint32, std::vector<CharPtr> >::iterator iter, ei = mapSameIPChars.end();
	for (iter = mapSameIPChars.begin(); iter != ei; ++iter)
	{
		*packet << uint8(iter->second.size());								// 同IP玩家数量
		std::vector<CharPtr>::iterator itChar, eiChar = iter->second.end();
		for (itChar = iter->second.begin(); itChar != eiChar; ++itChar)
		{
			if ((*itChar).isNull())
				return false;

			*packet << uint32((*itChar)->getHandle());						// 角色ID
			AppendPacketString<uint8>(packet, (*itChar)->getCharName());	// 角色昵称
		}
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建同意或拒绝游戏协议包 0x00EB
bool ProtocolsManager::CreateAgreeOrRefusePacket(WorldPacket * packet, const uint8 & agree, const uint32 & char_id, const uint8 & result)
{
	packet->clear();
	packet->SetOpcode(SMSG_CENTERBATTLE_AGREEORREFUSEPLAY);
	*packet << uint16(SMSG_CENTERBATTLE_AGREEORREFUSEPLAY) << uint16(0)
		<< uint32(char_id)					// 角色ID
		<< uint8(agree)						// 同意继续游戏（0 拒绝 1 同意）
		<< uint8(result);					// 结果（0 失败 1 成功）

	packet->SetLength(packet->size());
	return true;
}

// 棋牌圈牌桌相关信息0x2001
bool ProtocolsManager::CreateCenterBattleInfoPacket(WorldPacket * packet, String strCBInfo)
{
	if (!packet)
		return false;

	packet->clear();

	// 预开辟空间
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_CHANNELINFO);
	*packet << uint16(SMSG_CENTERBATTLE_CHANNELINFO) << uint16(0);

	AppendPacketString<uint16>(packet, strCBInfo);

	packet->SetLength(packet->size());
	return true;
}

// 玩家选择座位0x2002
bool ProtocolsManager::CreatePlayerChooseSeatPacket(WorldPacket * packet, const uint8 & pos, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_CHOOSEPOS);
	*packet << uint16(SMSG_CENTERBATTLE_CHOOSEPOS) << uint16(0)
		<< uint8(pos)											// 发起投票方座位
		<< uint8(result);											// 结果

	packet->SetLength(packet->size());
	return true;
}

// 发起投票0x2003
bool ProtocolsManager::CreateSendVotePacket(WorldPacket * packet, const uint32 & char_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_SENDVOTE);
	*packet << uint16(SMSG_CENTERBATTLE_SENDVOTE) << uint16(0)
		<< uint32(char_id)									// 发起投票方座位
		<< uint8(result);									// 结果

	packet->SetLength(packet->size());
	return true;
}

// 玩家投票列表0x2004
bool ProtocolsManager::CreateVoteListPacket(WorldPacket * packet, std::map<uint32, stVotePlayer> mapVote, const uint16 & think_time, const uint8 & status)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_VOTELIST);
	*packet << uint16(SMSG_CENTERBATTLE_VOTELIST) << uint16(0)
		<< uint8(status)									// 状态（0 投票中 1 解散 2 继续）
		<< uint16(think_time)								// 考虑时间
		<< uint8(mapVote.size());							// 玩家数量

	std::map<uint32, stVotePlayer>::iterator iter, ei = mapVote.end();
	for (iter = mapVote.begin(); iter != ei; ++iter)
	{
		*packet << uint32(iter->first)							// 角色ID
			<< uint8(iter->second.vote_status);				// 投票状态	
	}

	packet->SetLength(packet->size());
	return true;
}

// 解散牌局0x2005
bool ProtocolsManager::CreateDissolveChannelPacket(WorldPacket * packet, const uint8 & reson)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_CHANNELDISSOLVE);
	*packet << uint16(SMSG_CENTERBATTLE_CHANNELDISSOLVE) << uint16(0)
		<< uint8(reson);											// 解散原因

	packet->SetLength(packet->size());
	return true;
}

// 牌局开始前读秒 0x2006
bool ProtocolsManager::CreateWaitGameStartTimePcket(WorldPacket * packet, const uint32 & timer, const uint32 & type)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_WAIT_GAMESTART_TIME);
	*packet << uint16(SMSG_WAIT_GAMESTART_TIME) << uint16(0)
		<< uint32(timer)
		<< uint32(type);

	packet->SetLength(packet->size());
	return true;
}

// 赠送免费道具（鲜花，鸡蛋）0x2010
bool ProtocolsManager::CreateGiveFreeGiftPacket(WorldPacket * packet, const uint32 & send_charID, const uint8 & gift_id, std::vector<uint32> vCharIDs, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_GIVE_FREEGIFT);
	*packet << uint16(SMSG_GIVE_FREEGIFT) << uint16(0)
		<< uint32(send_charID)			// 发送方角色ID
		<< uint8(gift_id)				// 道具ID
		<< uint8(vCharIDs.size());		// 被赠送道具玩家数量

	std::vector<uint32>::iterator iter, ei = vCharIDs.end();
	for (iter = vCharIDs.begin(); iter != ei; ++iter)
	{
		*packet << uint32(*iter);
	}

	*packet << uint8(result);				// 结果（0 失败 1 成功 2 费用不足）
	packet->SetLength(packet->size());
	return true;
}

// 创建玩家请求是否可以进入组局 0x2011
bool ProtocolsManager::CreateRequireCanJoinCenterBattlePacket(WorldPacket * packet, String & join_code, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_REQUIRE_JOINCENTERBATTLE);
	*packet << uint16(SMSG_REQUIRE_JOINCENTERBATTLE) << uint16(0);

	AppendPacketString<uint8>(packet, join_code);
	*packet << uint8(result);							// 结果（1 成功 其他：失败）

	packet->SetLength(packet->size());
	return true;
}

// 创建组局公共房列表 0x2012
bool ProtocolsManager::CreateCenterBattlePublicListPacket(WorldPacket * packet, const uint32 & game_id, std::list<CenterBattle> vCb)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_PUBLICLIST);
	*packet << uint16(SMSG_CENTERBATTLE_PUBLICLIST) << uint16(0)
		<< uint32(game_id)
		<< uint32(vCb.size());
	
	std::list<CenterBattle>::iterator iter, ei = vCb.end();
	for (iter = vCb.begin(); iter != ei; ++iter)
	{
		// 查询在牌桌中的玩家数据
		Json::Reader reader;
		Json::Value val, val2;
		reader.parse((*iter).player, val);

		*packet << uint32((*iter).cb_id)							// 组局ID
				<< uint32((*iter).game_id);							// 游戏ID
		
		String fz_name = Base64Encode((*iter).name.c_str(), (*iter).name.size());
		
		reader.parse((*iter).sdata2, val2);
		val2["fz_name"] = fz_name;
		val2["fz_head"] = (*iter).head;
		val2["fz_pid"] = (*iter).pid;
		
		Json::FastWriter w;
		String strSdata2 = w.write(val2);
		
		AppendPacketString<uint16>(packet, strSdata2);				// 玩法设定（玩法数据设定）
		AppendPacketString<uint8>(packet, (*iter).join_code);		// 验证码
		
		*packet << uint16((*iter).max_player)						// 最大玩家数量
				<< uint16(val.size());								// 玩家数量
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建或加入随机组局房 0x2013
bool ProtocolsManager::CreateCreateOrJoinRandomCenterBattle(WorldPacket * packet, String strJoinCode, const uint16 & gz_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CREATEORJOIN_CENTERBATTLE);
	*packet << uint16(SMSG_CREATEORJOIN_CENTERBATTLE) << uint16(0);
	
	AppendPacketString<uint8>(packet, strJoinCode);		// 玩法数据
	*packet << uint32(gz_id)							// 分区ID
			<< uint8(result);							// 结果
	
	packet->SetLength(packet->size());
	return true;
}

// 获取斗地主公共房列表 0x2014（目前针对斗地主）
bool ProtocolsManager::CreateDDZPublicCenterBattleListPacket(WorldPacket * packet, const uint16 & room_id, const uint16 & hall_id, const uint16 & total_count, 
															const uint16 & offset, const uint16 & num, std::list<CenterBattle> lstBattles)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTER_GETDDZPUBLICBATTLELIST);
	*packet << uint16(SMSG_CENTER_GETDDZPUBLICBATTLELIST) << uint16(0)
			<< uint16(room_id)
			<< uint16(hall_id)
			<< uint16(total_count)
			<< uint16(offset)
			<< uint16(num)
			<< uint16(lstBattles.size());
	
	std::list<CenterBattle>::iterator iter, ei = lstBattles.end();
	for(iter = lstBattles.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).cb_id)			// 组局ID
				<< uint8((*iter).max_player)		// 最大人数
				<< uint8((*iter).status)			// 状态（3 等待 4 游戏中）
				<< uint32((*iter).base_coins);		// 底分
		
		AppendPacketString<uint8>(packet, (*iter).join_code);	// 房间号
		AppendPacketString<uint16>(packet, (*iter).sdata2);		// 玩法设定
		
		Json::Reader reader;
		Json::Value val;
		reader.parse((*iter).player, val);
		*packet << uint8(val.size());
		
		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			uint8 pos = 255;
			if((*iterVal).isMember("pos"))
				pos = (*iterVal)["pos"].asUInt();
			
			*packet << uint32((*iterVal)["pid"].asUInt())					// PID
					<< uint8((*iterVal)["player_status"].asUInt())			// 状态
					<< uint8(pos);											// 座位
			
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}

// 组局牌桌上锁结果 0x2015
bool ProtocolsManager::CreateSetBattleLockResutlPacket(WorldPacket * packet, const uint32 & cb_id, String passwd, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTER_LOCKDDZPUBLICBATTLE);
	*packet << uint16(SMSG_CENTER_LOCKDDZPUBLICBATTLE) << uint16(0)
			<< uint32(cb_id);
	
	AppendPacketString<uint8>(packet, passwd);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

// SMSG_CENTER_CHANGECENTERBATTLE = 0x2016,		组局换桌
bool ProtocolsManager::CreateChangeCenterBattlePacket(WorldPacket * packet, const uint32 & cb_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTER_CHANGECENTERBATTLE);
	*packet << uint16(SMSG_CENTER_CHANGECENTERBATTLE) << uint16(0)
			<< uint32(cb_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

// 创建组局房间玩家信息 0x2020
bool ProtocolsManager::CreateCenterBattlePlayerInfoPacket(WorldPacket * packet, CenterBattle cb)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(CMSG_CENTERBATTLE_PLAYERINFO);
	*packet << uint16(CMSG_CENTERBATTLE_PLAYERINFO) << uint16(0)
		<< uint32(cb.cb_id)			// 组局ID
		<< uint16(cb.game_id);		// 游戏ID

// 牌桌附加数据2
	AppendPacketString<uint16>(packet, cb.sdata3);
	Log.Debug("CreateCenterBattlePlayerInfoPacket", "cb_id[%u] sdata3[%s]", cb.cb_id, cb.sdata3.c_str());

	Json::Reader reader;
	Json::Value val;
	reader.parse(cb.player, val);

	*packet << uint8(val.size());
	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		// Json版本
		Json::Value val;
		val["name"] = string_url_decode((*iterVal)["name"].asString());						// 昵称
		val["icon"] = string_url_decode((*iterVal)["desc"].asString());						// 头像
		val["pid"] = uint32(StringConverter::parseUnsignedInt(iterVal.key().asString()));	// PID
		val["score"] = int32((*iterVal)["winlose"].asInt());								// 当前积分
		val["play_count"] = uint32((*iterVal)["player_count"].asUInt());					// 游戏局数
		val["status"] = uint32((*iterVal)["player_status"].asUInt());						// 玩家状态

		Json::FastWriter w;
		String strJsonData = w.write(val);

		AppendPacketString<uint16>(packet, strJsonData);
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建玩家最近组局单场记录信息 0x2021
bool ProtocolsManager::CreateCenterBattlePlayerSingleLogPacket(WorldPacket * packet, 
																const uint32 & offset,
																const uint32 & total_count, 
																std::list<CenterBattleLog> logs)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_PLAYERSINGLELOGS);
	*packet << uint16(SMSG_CENTERBATTLE_PLAYERSINGLELOGS) << uint16(0)
			<< uint32(total_count)						// 日志总数
			<< uint32(offset)							// 偏移起始位置
			<< uint16(logs.size());						// 实际日志数量
	
	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for(iter = logs.begin(); iter!=ei; ++iter)
	{
		Json::Value val;
		val["video"] = (*iter).data6;						// 是否有录像(0 没 1 有)
		val["create_time"] = (*iter).create_time;			// 组局创建时间
		val["game_name"] = (*iter).sdata1;					// 游戏名
		
		Json::Value valPlayer;
		Json::Reader reader;
		
		reader.parse((*iter).sdata5, valPlayer);
		if (valPlayer.isMember("players"))
		{
			uint8 index = 0;
			for (Json::Value::iterator iterVal = valPlayer["players"].begin(); iterVal != valPlayer["players"].end(); ++iterVal)
			{
				Json::Value val2;
				val2["pid"] = (*iterVal)["pid"].asUInt();					// PID
				val2["winlose"] = (*iterVal)["winlose"].asInt();			// 输赢
				val2["name"] = (*iterVal)["name"].asString();				// 昵称
				
				if((*iterVal).isMember("json_data"))
				{
					Json::Value valData;
					reader.parse((*iterVal)["json_data"].asString(), valData);
					if(valData.isMember("isBanker"))
						val2["isBanker"] = valData["isBanker"].asUInt();	// 地主农民
				}
				
				val["players"][index++] = val2;								// 循环数据
			}
		}
		
		Json::FastWriter w;
		AppendPacketString<uint16>(packet, w.write(val));					// 记录数据json
	}
	
	packet->SetLength(packet->size());
	return true;
}

// 创建某分区某房间玩家数量
bool ProtocolsManager::CreateTownPlayerCountByGzid(WorldPacket * packet, const uint32 & gz_id, const uint32 & town_id, const uint32 & num)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_COMMON_GETTOWNPLAYERCOUNT);
	*packet << uint16(SMSG_COMMON_GETTOWNPLAYERCOUNT) << uint16(0)
			<< uint32(gz_id)
			<< uint32(town_id)
			<< uint32(num);
	
	packet->SetLength(packet->size());
	return true;
}

// SMSG_CENTERBATTLE_MATCHZONELOGS = 0x2023,		// 赛区战绩记录列表
bool ProtocolsManager::CreateCenterBattleMatchZoneLogsPacket(WorldPacket * packet, 
															const uint32 & zone_id, 
															const uint32 & offset, 
															const uint32 & total_count, 
															std::list<CenterBattleLog> logs)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CENTERBATTLE_MATCHZONELOGS);
	*packet << uint16(SMSG_CENTERBATTLE_MATCHZONELOGS) << uint16(0)
			<< uint32(zone_id)							// 赛区ID
			<< uint32(total_count)						// 日志总数
			<< uint32(offset)							// 偏移起始位置
			<< uint16(logs.size());						// 实际日志数量
	
	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for(iter = logs.begin(); iter!=ei; ++iter)
	{
		Json::Value val;
		val["video"] = (*iter).data6;						// 是否有录像(0 没 1 有)
		val["create_time"] = (*iter).create_time;			// 组局创建时间
		val["game_name"] = (*iter).sdata1;					// 游戏名
		
		Json::Value valPlayer;
		Json::Reader reader;
		
		reader.parse((*iter).sdata5, valPlayer);
		if (valPlayer.isMember("players"))
		{
			uint8 index = 0;
			for (Json::Value::iterator iterVal = valPlayer["players"].begin(); iterVal != valPlayer["players"].end(); ++iterVal)
			{
				Json::Value val2;
				val2["pid"] = (*iterVal)["pid"].asUInt();					// PID
				val2["winlose"] = (*iterVal)["winlose"].asInt();			// 输赢
				val2["name"] = (*iterVal)["name"].asString();				// 昵称
				
				if((*iterVal).isMember("json_data"))
				{
					Json::Value valData;
					reader.parse((*iterVal)["json_data"].asString(), valData);
					if(valData.isMember("isBanker"))
						val2["isBanker"] = valData["isBanker"].asUInt();	// 地主农民/庄家与否
				}
				
				val["players"][index++] = val2;								// 循环数据
			}
		}
		
		Json::FastWriter w;
		AppendPacketString<uint16>(packet, w.write(val));					// 记录数据json
	}
	
	packet->SetLength(packet->size());
	return true;
}

// 创建公共活动信息 0x2030
bool ProtocolsManager::CreateCommonActivityInfoPacket(WorldPacket * packet, const uint32 & agent_id, EffectPtr & effectPtr)
{
	/* if(!packet || effectPtr.isNull())
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_COMMON_ACTIVITYINFO);
	*packet << uint16(SMSG_COMMON_ACTIVITYINFO) << uint16(0);

	Json::Value val;
	Json::Reader reader;

	String info = effectPtr->getStringField("info");
	reader.parse(info, val);

	uint8 offset = packet->size();
	uint8 effect_num = 0;
	*packet << uint8(0);

	for(Json::Value::iterator iter=val.begin(); iter!=val.end(); ++iter)
	{
		*packet << uint32((*iter)["id"].asUInt())				// 活动ID
				<< uint32((*iter)["type"].asUInt())				// 活动类型
				<< uint8((*iter)["status"].asUInt())			// 活动状态(0 未完成 1 完成)
				<< uint32((*iter)["curr_count"].asUInt());		// 当前完成数量

		stSingleActivity single_acti = sActivityMgr.GetSingleAcitvityByAgentidAndAcitvityID(m_agent_id, (*iter)["id"].asUInt());
		if(single_acti.id == 0)
			continue;

		*packet << uint32(single_acti.need_count)			// 目标完成数量
				<< uint32(single_acti.finish_count)			// 总共可完成次数
				<< uint8(single_acti.mapBounties.size());	// 奖励种类

		// 奖励
		std::map<uint32, uint32>::iterator itBounty, eiBounty = single_acti.mapBounties.end();
		for(itBounty = single_acti.mapBounties.begin(); itBounty!=eiBounty; ++itBounty)
		{
			*packet << uint32(itBounty->first)
					<< uint32(itBounty->second);
		}

		AppendPacketString<uint8>(packet, (*iter)["tittle"].asString());	// 标题
		AppendPacketString<uint8>(packet, (*iter)["content"].asString());	// 内容
		AppendPacketString<uint8>(packet, (*iter)["bgicon"].asString());	// 背景图片url
		++effect_num;
	}

	packet->SetOffset(offset, effect_num);
	packet->SetLength(packet->size()); */
	return true;
}

// 创建公共用户信息 0x2032
bool ProtocolsManager::CreateCommonUserConfigInfoPacket(WorldPacket * packet, const uint32 & platform_id, const uint32 & gz_id, String strConfig)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(CMSG_CENTERBATTLE_PLAYERINFO);
	*packet << uint16(CMSG_CENTERBATTLE_PLAYERINFO) << uint16(0)
		<< uint32(platform_id)
		<< uint32(gz_id);

	AppendPacketString<uint16>(packet, strConfig);	// 用户信息（json字符串格式）

	packet->SetLength(packet->size());
	return true;
}

// 创建公共签到信息包 0x2033
bool ProtocolsManager::CreateCommonSignInfoPacket(WorldPacket * packet, stCommonSign cs)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_COMMON_SIGNINFO);
	*packet << uint16(SMSG_COMMON_SIGNINFO) << uint16(0)
		<< uint8(cs.combo_days)			// 连签天数
		<< uint8(cs.count_days)			// 累签天数
		<< uint8(cs.sign_sub_mode);		// 签到类型（1 周签，2 月签到）

	*packet << uint8(cs.vSignInfo.size());
	std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vSignInfo.end();
	for (iter = cs.vSignInfo.begin(); iter != ei; ++iter)
	{
		if (cs.sign_sub_mode == 1)
		{// 周签（周几）
			*packet << uint8((*iter).stCSS.week);
		}
		else
		{// 月签（日期）
			*packet << uint8((*iter).stCSS.day);
		}

		*packet << uint8((*iter).status)
				<< uint8((*iter).stCSS.mapBounties.size());

		std::map<uint32, uint32>::iterator itBounty, eiBounty = (*iter).stCSS.mapBounties.end();
		for (itBounty = (*iter).stCSS.mapBounties.begin(); itBounty != eiBounty; ++itBounty)
		{
			*packet << uint32(itBounty->first)		// 道具ID
					<< uint32(itBounty->second);	// 道具数量
		}
	}

	*packet << uint8(cs.vComboInfo.size());
	std::vector<stCommonSingleSignResult>::iterator iterC, eiC = cs.vComboInfo.end();
	for (iterC = cs.vComboInfo.begin(); iterC != eiC; ++iterC)
	{
		*packet << uint8((*iterC).stCSS.days)
				<< uint8((*iterC).status)
				<< uint8((*iterC).stCSS.mapBounties.size());

		std::map<uint32, uint32>::iterator itBounty, eiBounty = (*iterC).stCSS.mapBounties.end();
		for (itBounty = (*iterC).stCSS.mapBounties.begin(); itBounty != eiBounty; ++itBounty)
		{
			*packet << uint32(itBounty->first)		// 道具ID
					<< uint32(itBounty->second);	// 道具数量
		}
	}

	*packet << uint8(cs.vCountInfo.size());
	std::vector<stCommonSingleSignResult>::iterator iterCount, eiCount = cs.vCountInfo.end();
	for (iterCount = cs.vCountInfo.begin(); iterCount != eiCount; ++iterCount)
	{
		*packet << uint8((*iterCount).stCSS.days)
			<< uint8((*iterCount).status)
			<< uint8((*iterCount).stCSS.mapBounties.size());

		std::map<uint32, uint32>::iterator itBounty, eiBounty = (*iterCount).stCSS.mapBounties.end();
		for (itBounty = (*iterCount).stCSS.mapBounties.begin(); itBounty != eiBounty; ++itBounty)
		{
			*packet << uint32(itBounty->first)		// 道具ID
				<< uint32(itBounty->second);	// 道具数量
		}
	}

	packet->SetLength(packet->size());
	return true;
}

// 创建签到结果信息包 0x2034
bool ProtocolsManager::CreateCommonSignResultPacket(WorldPacket * packet, const uint8 & sign_type, const uint8 & data, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_COMMON_SIGN);
	*packet << uint16(SMSG_COMMON_SIGN) << uint16(0)
		<< uint8(sign_type)
		<< uint8(data)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

// 创建个性签名信息包 0x2035
bool ProtocolsManager::CreateCommonSignNamePacket(WorldPacket * packet, const uint32 & platform_id, String & content)
{
	if (!packet)
		return false;

	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_COMMON_SIGNNAME);
	*packet << uint16(SMSG_COMMON_SIGNNAME) << uint16(0)
			<< uint32(platform_id);

	AppendPacketString<uint16>(packet, content);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_GameStatus = 0x2500,	//游戏状态
bool ProtocolsManager::CreateMJGameStatusPacket(WorldPacket * packet, const CMD_GameStart & gamestart)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_GameStatus);
	*packet << uint16(SMSS_MJ_GameStatus) << uint16(5)
		<< gamestart.ui8GameStatus
		<< gamestart.ui8BankerPos
		<< gamestart.ui8LeftCardCount
		<< gamestart.ui8DongFengSeat;
	*packet << uint8(gamestart.vecDicePoint.size());
	for (uint8 i = 0; i < gamestart.vecDicePoint.size(); i++)
	{
		*packet << uint8(gamestart.vecDicePoint[i]);
	}
	*packet << uint8(gamestart.ui8SendCardPos);
	*packet << uint8(gamestart.ui8FirstDispatchCardPos);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_MagicCard = 0x2501,	//癞子牌列表
bool ProtocolsManager::CreateMJMagicCardsListPacket(WorldPacket * packet, std::vector<uint8> vecMagicCards, const uint8 & ui8PlayerPosID)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_MagicCard);
	*packet << uint16(SMSS_MJ_MagicCard) << uint16(5);
	*packet << uint8(vecMagicCards.size());

	for (uint8 i = 0; i < vecMagicCards.size(); i++)
	{
		*packet << vecMagicCards[i];
	}
	*packet << ui8PlayerPosID;

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_HandCard = 0x2502,	//玩家手牌
bool ProtocolsManager::CreateMJHandCardPacket(WorldPacket * packet, std::vector<uint8> vecHandCardsList, const uint8 & type)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_HandCard);
	*packet << uint16(SMSS_MJ_HandCard) << uint16(5)
		<< uint8(vecHandCardsList.size());
	for (size_t i = 0; i < vecHandCardsList.size(); i++)
	{
		*packet << uint8(vecHandCardsList[i]);
	}
//	*packet << type;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_BuHuaCard = 0x2503,	//补花
bool ProtocolsManager::CreateMJBuHuaListPacket(WorldPacket * packet, const uint8 & ui8PlayerChairID, const uint8 & ui8HuaPai)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_BuHuaCard);
	*packet << uint16(SMSS_MJ_BuHuaCard) << uint16(5)
		<< uint8(ui8PlayerChairID)
		<< uint8(1)
		<< uint8(ui8HuaPai)
		<< uint8(0);
		/*
		<< uint8(vecBuHuaCards.size());
	for (size_t i = 0; i < vecBuHuaCards.size(); i++)
	{
		*packet << uint8(vecBuHuaCards[i]);
	}
	*packet << uint8(vecNewCardList.size());
	for (size_t i = 0; i < vecNewCardList.size(); i++)
	{
		*packet << uint8(vecNewCardList[i]);
	}
	packet->SetLength(packet->size());
	return true;*/
	return true;
}

//SMSS_MJ_GiveCard = 0x2504,	//摸牌
bool ProtocolsManager::CreateMJSendCardPacket(WorldPacket * packet, CMD_SendCard & SendCard, bool bAction)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_GiveCard);
	*packet << uint16(SMSS_MJ_GiveCard) << uint16(5);
	*packet << SendCard.ui8CurrentPos;
	*packet << SendCard.ui8CardData;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OutCardNotify = 0x2505,	//通知出牌
bool ProtocolsManager::CreateMJCastCardNotify(WorldPacket * packet, const uint8 & ui8PlayerChairID, const uint32 & ui32LeftTime)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OutCardNotify);
	*packet << uint16(SMSS_MJ_OutCardNotify) << uint16(5)
		<< ui8PlayerChairID
		<< uint8(ui32LeftTime / 1000);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OutCard = 0x2506,		//出牌 对玩家自己
bool ProtocolsManager::CreateMJOutCardPacket(WorldPacket * packet, const uint8 & ui8OutCardData, const uint8 & ui8OutResult)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OutCard);
	*packet << uint16(SMSS_MJ_OutCard) << uint16(10)
		<< uint8(ui8OutResult)
		<< uint8(ui8OutCardData);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OutCardForAllPlayer = 0x2507,	//玩家出牌 对所有玩家
bool ProtocolsManager::CreateMJOutCardForAllPlayerPacket(WorldPacket * packet, const uint8 & ui8PlayerChairId, const uint8 & ui8CardData)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OutCardForAllPlayer);
	*packet << uint16(SMSS_MJ_OutCardForAllPlayer) << uint16(5);
	*packet << ui8PlayerChairId
			<< ui8CardData;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OperateNotify = 0x2508,		//动作提示
bool ProtocolsManager::CreateMJOperateNotifyPacket(WorldPacket * packet, CMD_OperateNotify & OperateNotify)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OperateNotify);
	*packet << uint16(SMSS_MJ_OperateNotify) << uint16(10)
		<< OperateNotify.ui8ResumePos
		<< OperateNotify.ui8ActionCard
		<< OperateNotify.ui8ActionMask
		<< uint8(OperateNotify.ui32LeftTime / 1000);
	//========吃牌列表==============
	std::map<uint8, uint8> temp;
	for (uint8 i = 0; i < OperateNotify.m_VPlayerChiCardList.size(); i++)
	{
		std::vector<uint8> temp2 = OperateNotify.m_VPlayerChiCardList[i];
		for (uint8 t = 0; t < temp2.size(); t++)
		{
			temp[temp2[0]] = 1;
			break;
		}
	}
	*packet << uint8(temp.size());
	std::map<uint8, uint8>::iterator iter = temp.begin();
	for (; iter != temp.end(); ++iter)
	{
		*packet << uint8(1);
		*packet << uint8(iter->first);
	}
	////===================全牌信息====================
	/**packet << uint8(OperateNotify.m_VPlayerChiCardList.size());
	for (uint8 i = 0; i < OperateNotify.m_VPlayerChiCardList.size(); i++)
	{
		std::vector<uint8> temp = OperateNotify.m_VPlayerChiCardList[i];
		*packet << uint8(temp.size());
		for (uint8 t = 0; t < temp.size(); t++)
		{
			*packet << uint8(temp[t]);
		}
	}*/
	temp.clear();
	//========碰牌列表==============

	for (uint8 i = 0; i < OperateNotify.m_VPlayerPengCardList.size(); i++)
	{
		std::vector<uint8> temp2 = OperateNotify.m_VPlayerPengCardList[i];
		for (uint8 t = 0; t < temp2.size(); t++)
		{
			temp[temp2[0]] = 1;
			break;
		}
	}
	if (temp.size())
		*packet << uint8(temp.begin()->first);
	else
		*packet << uint8(0);
	//*packet << uint8(temp.size());
	//for (iter = temp.begin(); iter != temp.end(); ++iter)
	//{
	//	*packet << uint8(1);
	//	*packet << uint8(iter->first);
	//}
	//*packet << uint8(OperateNotify.m_VPlayerPengCardList.size());
	/*for (uint8 i = 0; i < OperateNotify.m_VPlayerPengCardList.size(); i++)
	{
		std::vector<uint8> temp = OperateNotify.m_VPlayerPengCardList[i];
		*packet << uint8(temp.size());
		for (uint8 t = 0; t < temp.size(); t++)
		{
			*packet << uint8(temp[t]);
		}
	}*/
	temp.clear();
	//========杠牌列表==============
	for (uint8 i = 0; i < OperateNotify.m_VPlayerGangCardList.size(); i++)
	{
		std::vector<uint8> temp2 = OperateNotify.m_VPlayerGangCardList[i];
		for (uint8 t = 0; t < temp2.size(); t++)
		{
			temp[temp2[0]] = 1;
			break;
		}
	}
	*packet << uint8(temp.size());
	for (iter = temp.begin(); iter != temp.end(); ++iter)
	{
		*packet << uint8(1);
		*packet << uint8(iter->first);
	}
	/**packet << uint8(OperateNotify.m_VPlayerGangCardList.size());
	for (uint8 i = 0; i < OperateNotify.m_VPlayerGangCardList.size(); i++)
	{
		std::vector<uint8> temp = OperateNotify.m_VPlayerGangCardList[i];
		*packet << uint8(temp.size());
		for (uint8 t = 0; t < temp.size(); t++)
		{
			*packet << uint8(temp[t]);
		}
	}*/
	//========听牌列表==============
	*packet << uint8(OperateNotify.m_MPlayerTingCardList.size());
	std::map<uint8, std::vector<uint8> >::iterator Titer, ei = OperateNotify.m_MPlayerTingCardList.end();
	for (Titer = OperateNotify.m_MPlayerTingCardList.begin(); Titer != ei; ++Titer)
	{
		*packet << uint8(Titer->first);
		*packet << uint8(Titer->second.size());
		for (uint8 t = 0; t < Titer->second.size(); t++)
		{
			*packet << uint8(Titer->second[t]);
		}
	}
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_Operate = 0x2509,		//玩家进行操作
bool ProtocolsManager::CreateMJOperatePacket(WorldPacket * packet, const uint8 & ui8Action, const uint8 & ui8OperateCard, const uint8 & ui8Result)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_Operate);
	*packet << uint16(SMSS_MJ_Operate) << uint16(10)
		<< ui8Result
		<< ui8Action
		<< ui8OperateCard;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OperateChiPengGang = 0x250A,		//玩家吃碰杠
bool ProtocolsManager::CreateMJOperatePengGangPacket(WorldPacket * packet, const uint8 & ui8PlayerChairID, tagWeaveItem & WeaveItem, const uint8 & m_ui8ProvideCard)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OperateChiPengGang);
	uint8 ui8CenterCard = 0;
	ui8CenterCard = WeaveItem.ui8CenterCard;
	/*if (ui8PlayerChairID == WeaveItem.ui8ProvidePos)
	{
		ui8CenterCard = WeaveItem.ui8CenterCard;
	}
	else
	{
		if (WeaveItem.ui8Type != 0)
		{
			ui8CenterCard = WeaveItem.ui8CenterCard;
		}
	}*/
	if (WeaveItem.ui8WeaveKind == WIK_LEFT)
	{
		ui8CenterCard = m_ui8ProvideCard;
	}
	*packet << uint16(SMSS_MJ_OperateChiPengGang) << uint16(10)
		<< ui8PlayerChairID
		<< WeaveItem.ui8WeaveKind
		<< (WeaveItem.ui8Type == enGangType_MingGang ? WeaveItem.ui8ProvidePos : ui8PlayerChairID)
		<< uint8(ui8CenterCard) //核心牌牌值，别人暗杠为0
		<< uint8(WeaveItem.ui8Type);
	uint8 ui8CardNum = WeaveItem.ui8WeaveKind == WIK_GANG ? 4 : 3;
//	ui8CardNum = 0;
	*packet << uint8(ui8CardNum);
	for (uint8 i = 0; i < ui8CardNum; i++)
	{
		*packet << uint8(WeaveItem.ui8CardData[i]);//具体牌值，别人暗杠为0
		//*packet << uint8((ui8PlayerChairID == WeaveItem.ui8ProvidePos ? WeaveItem.ui8CardData[i] : (WeaveItem.ui8Type ? WeaveItem.ui8CardData[i] : 0)));//具体牌值，别人暗杠为0
	}
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OperateListen = 0x250B,		//玩家听牌
bool ProtocolsManager::CreateMJOperateListenPacket(WorldPacket * packet, const uint8 & ui8PlayerChairID)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OperateListen);
	*packet << uint16(SMSS_MJ_OperateListen) << uint16(10)
		<< ui8PlayerChairID;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_OperateHu = 0x250C,		//玩家胡
bool ProtocolsManager::CreateMJOperateHuPacket(WorldPacket * packet,
	const uint8 & ui8PlayerChairID,
	std::vector<uint8> vecCardslist,
	std::vector<tagWeaveItem>& vecWeaveItem,
	const uint8 & ui8CenterCard,
	const uint8 & ui8HuFanXing,
	const uint8 & ui8ProvidePos,
	const uint8 & ui8HuType,
	const uint32 & ui32ExData)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_OperateHu);
	*packet << uint16(SMSS_MJ_OperateHu) << uint16(10)
		<< ui8PlayerChairID
		<< ui8ProvidePos
		<< ui8HuFanXing;
	*packet << uint8(ui8CenterCard);
	*packet << ui32ExData;
	*packet << uint8(vecCardslist.size());
	for (size_t i = 0; i < vecCardslist.size(); i++)
	{
		*packet << uint8(vecCardslist[i]);
	}

	*packet << uint8(vecWeaveItem.size());
	for (uint8 i = 0; i < vecWeaveItem.size(); i++)
	{
		*packet << vecWeaveItem[i].ui8WeaveKind
			<< vecWeaveItem[i].ui8CenterCard
			<< vecWeaveItem[i].ui8Type;
		uint8 ui8CardNum = vecWeaveItem[i].ui8WeaveKind == WIK_GANG ? 4 : 3;
		*packet << uint8(ui8CardNum);
		for (uint8 t = 0; t < ui8CardNum; t++)
		{
			*packet << uint8(vecWeaveItem[i].ui8CardData[t]);
		}
	}
	*packet << ui8HuType;
	Log.Debug("ProtocolsManager::CreateMJOperateHuPacket", "ui8HuType:%d", ui8HuType);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_Animation = 0x250D,		//牌桌动画
bool ProtocolsManager::CreateMJAnimationPacket(WorldPacket * packet, const uint8 & ui8PlayerChairID, const uint8 & ui8AnimationType)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_Animation);
	*packet << uint16(SMSS_MJ_Animation) << uint16(10)
		<< ui8PlayerChairID
		<< ui8AnimationType;

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_LiangPai = 0x250E,	//亮牌
bool ProtocolsManager::CreateMJLiangPaiPacket(WorldPacket * packet, std::vector<std::vector<uint8> >& vecCardsList, std::vector<std::vector<tagWeaveItem> >& vecWeave, bool bLiuJu)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_LiangPai);
	*packet << uint16(SMSS_MJ_LiangPai) << uint16(10);

	*packet << uint8(vecCardsList.size());
	for (uint8 i = 0; i < vecCardsList.size(); i++)
	{
		std::vector<uint8> temp = vecCardsList[i];
		*packet << uint8(temp.size());
		for (uint8 t = 0; t < temp.size(); t++)
		{
			*packet << uint8(temp[t]);
		}
		std::vector<tagWeaveItem> temp2 = vecWeave[i];
		*packet << uint8(temp2.size());
		for (uint8 t = 0; t < temp2.size(); t++)
		{
			*packet << temp2[t].ui8WeaveKind
				<< temp2[t].ui8CenterCard
				<< temp2[t].ui8Type;
			uint8 ui8CardNum = temp2[i].ui8WeaveKind == WIK_GANG ? 4 : 3;
			*packet << uint8(ui8CardNum);
			for (uint8 p = 0; p < ui8CardNum; p++)
			{
				*packet << uint8(temp2[t].ui8CardData[p]);
			}
		}
	}

	*packet << uint8(bLiuJu);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_PlayerStatus = 0x250F,//玩家状态
bool ProtocolsManager::CreateMJPlayerStatusPacket(WorldPacket * packet, const uint8 & ui8PlayerChairID, const uint8 & ui8Status)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_PlayerStatus);
	*packet << uint16(SMSS_MJ_PlayerStatus) << uint16(6)
		<< ui8PlayerChairID
		<< uint8((ui8Status == enPlayer_AutoHuPai) ? enPlayer_Normal: ui8Status);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_Reconnection = 0x2510,//玩家重新连接连接
bool ProtocolsManager::CreateMJReconnectionPacket(WorldPacket * packet,
	std::vector<uint8> vecHandCardsList,
	std::vector<uint8> vecPlayerCardCount,
	std::vector<std::vector<tagWeaveItem> > vecWeaveItem,
	std::vector<std::vector<uint8> > vecPlayerDiscardCard,
	uint8 ui8LastCard)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_Reconnection);
	*packet << uint16(SMSS_MJ_Reconnection) << uint16(10);
	*packet << uint8(vecHandCardsList.size());
	for (size_t i = 0; i < vecHandCardsList.size(); i++)
	{
		*packet << uint8(vecHandCardsList[i]);
	}

	*packet << uint8(vecWeaveItem.size());
	for (uint8 i = 0; i < vecWeaveItem.size(); i++)
	{
		*packet << uint8(i);
		*packet << uint8(vecPlayerCardCount[i]);
		*packet << uint8(vecWeaveItem[i].size());
		for (uint8 t = 0; t < vecWeaveItem[i].size(); t++)
		{
			*packet << vecWeaveItem[i][t].ui8WeaveKind
				//<< uint8((i == vecWeaveItem[i][t].ui8ProvidePos ? vecWeaveItem[i][t].ui8CenterCard : (vecWeaveItem[i][t].ui8Type ? vecWeaveItem[i][t].ui8CenterCard : 0)))
				<< uint8(vecWeaveItem[i][t].ui8CenterCard )
				<< vecWeaveItem[i][t].ui8Type;
			uint8 ui8CardNum = vecWeaveItem[i][t].ui8WeaveKind == WIK_GANG ? 4 : 3;
			*packet << uint8(ui8CardNum);
			for (uint8 q = 0; q < ui8CardNum; q++)
			{
				*packet << uint8(vecWeaveItem[i][t].ui8CardData[q]);
				//*packet << uint8((i == vecWeaveItem[i][t].ui8ProvidePos ? vecWeaveItem[i][t].ui8CardData[t] : (vecWeaveItem[i][t].ui8Type ? vecWeaveItem[i][t].ui8CardData[t] : 0)));
			}
		}

		*packet << uint8(vecPlayerDiscardCard[i].size());
		for (uint8 t = 0; t < vecPlayerDiscardCard[i].size(); t++)
		{
			*packet << uint8(vecPlayerDiscardCard[i][t]);
		}
	}
	*packet << uint8(ui8LastCard);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_XuanQueNotify = 0x2511,//选缺通知
bool ProtocolsManager::CreateMJXuanQueNotifyPacket(WorldPacket * packet, uint8 vecDefaultCards, const uint32 & ui32LeftTime)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_XuanQueNotify);
	*packet << uint16(SMSS_MJ_XuanQueNotify) << uint16(6)
		<< vecDefaultCards;
	*packet << uint8(ui32LeftTime / 1000);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_PlayerXuanQue = 0x2512,//玩家选缺结果
bool ProtocolsManager::CreateMJPlayerXuanQueResultPacket(WorldPacket * packet, uint8 vecDefaultCards, const uint8 & ui8Result)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_PlayerXuanQue);
	*packet << uint16(SMSS_MJ_PlayerXuanQue) << uint16(6)
		<< ui8Result
		<< vecDefaultCards;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_XuanQueList = 0x2513,//广播选缺结果
bool ProtocolsManager::CreateMJXuanQueListPacket(WorldPacket * packet, std::vector<uint8> vecXuanQueList, bool bAction)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_XuanQueList);
	*packet << uint16(SMSS_MJ_XuanQueList) << uint16(6);
	*packet << uint8(vecXuanQueList.size());
	for (uint8 i = 0; i < vecXuanQueList.size(); i++)
	{
		*packet << uint8(vecXuanQueList[i]);
	}
	*packet << bAction;
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_SwapCardNotify = 0x2514,//通知换牌
bool ProtocolsManager::CreateMJSwapCardsNotifyPacket(WorldPacket * packet, std::vector<uint8> vecDefaultCards, const uint32 & ui32LeftTime)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_SwapCardNotify);
	*packet << uint16(SMSS_MJ_SwapCardNotify) << uint16(6);
	*packet << uint8(vecDefaultCards.size());
	for (uint8 i = 0; i < vecDefaultCards.size(); i++)
	{
		*packet << uint8(vecDefaultCards[i]);
	}
	*packet << uint8(ui32LeftTime / 1000);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_PlayerSwapCard = 0x2515,		//玩家换牌
bool ProtocolsManager::CreateMJPlayerSwapCardsResultPacket(WorldPacket * packet, std::vector<uint8> vecDefaultCards, const uint8 & ui8Result)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_PlayerSwapCard);
	*packet << uint16(SMSS_MJ_PlayerSwapCard) << uint16(6);
	*packet << uint8(ui8Result);
	*packet << uint8(vecDefaultCards.size());
	for (uint8 i = 0; i < vecDefaultCards.size(); i++)
	{
		*packet << uint8(vecDefaultCards[i]);
	}
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_SwapCardList = 0x2516,		//换牌结果
bool ProtocolsManager::CreateMJSwapCardsResultPacket(WorldPacket * packet, std::vector<uint8> vecGetCards, const uint8 & uiFrom)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_SwapCardList);
	*packet << uint16(SMSS_MJ_SwapCardList) << uint16(6);
	*packet << uint8(uiFrom);
	*packet << uint8(vecGetCards.size());
	for (uint8 i = 0; i < vecGetCards.size(); i++)
	{
		*packet << uint8(vecGetCards[i]);
	}
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_PlayerInfo = 0x2517,		//麻将框架玩家列表
bool ProtocolsManager::CreateMJPlayerInfoPacket(WorldPacket * packet, MJBaseTablePlayer *  pMJTablePlayer)
{
	if (!packet || pMJTablePlayer == NULL || pMJTablePlayer->player.isNull())
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_PlayerInfo);
	*packet << uint16(SMSS_MJ_PlayerInfo) << uint16(5);

	*packet << uint32(pMJTablePlayer->player._handle);
	uint32 money = 0;

	uint32 pid = 0;
	CharPtr pChr = sCharMgr.load(pMJTablePlayer->player._handle);
	if (!pChr.isNull())
	{
		if (pMJTablePlayer->ui8PayMode == 3)
		{
			money = sGLMgr.GetItemNum(pChr, ItemModel_Coins);
			Log.Debug("ProtocolsManager::CreateMJPlayerInfoPacket", "Chr[%d]  club_id[%d]", pMJTablePlayer->player._handle, pMJTablePlayer->ui32ClubId);
			if (pMJTablePlayer->ui32ClubId != 0)
			{
				money = sCenterClubMemberMgr.GetMemberCurrCoins(pMJTablePlayer->ui32ClubId, pChr);
				Log.Debug("ProtocolsManager::CreateMJPlayerInfoPacket", "money[%d]", money);
			}
		}
		UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		if (pUser.isNull())
		{
			pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		}

		if (!pUser.isNull())
			pid = pUser->getUInt32Field("platform_id");
	}
	if (pChr.isNull())
	{
		*packet << int32(0)
			<< uint32(0)
			<< uint8(0)
			<< uint8(pMJTablePlayer->pos)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint32(pid)
			<< double(0)		//经度纬度海拔
			<< double(0)
			<< double(0)
			<< uint8(0);
		*packet << int8(0);

	}
	else
	{
		*packet << int32(pMJTablePlayer->score)									// 积分
			<< uint32(money)					//钱
			<< uint8(pMJTablePlayer->bFZ)										// 房主标志
			<< uint8(pMJTablePlayer->pos)										// 座位号
			<< uint8(pMJTablePlayer->playerJoinState);							// 是否准备

		AppendPacketString<uint8>(packet, pChr->getStringField("name"));	// 名字
		AppendPacketString<uint8>(packet, pChr->getStringField("desc"));	// 头像
																		
		sGLMgr.PacketPlayerSameInfo(packet, pChr);							// 地址
		*packet << uint32(pid);
		double j = 0, w = 0, h = 0;
		sGLMgr.GetUserLongitudeAndLatitude(pid, j, w, h);
		*packet << (j)<< (w)<< (h);
		WSSocketPtr socket = pChr->getSocket();
		String ip = "";
		if (!socket.isNull())
		{
			ip = socket->GetIP();
		}
		AppendPacketString<uint8>(packet, ip);
		*packet << int8(pChr->getUInt32Field("sex"));
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_WatchList = 0x2518,			//观战列表
bool ProtocolsManager::CreateMJWatchListPacket(WorldPacket * packet, std::map<uint32, MJBaseTablePlayer>& mapWatchList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_WatchList);
	*packet << uint16(SMSS_MJ_WatchList) << uint16(6);

	*packet << uint8(mapWatchList.size());
	std::map<uint32, MJBaseTablePlayer >::iterator iter, ei = mapWatchList.end();
	for (iter = mapWatchList.begin(); iter != ei; ++iter)
	{
		CharPtr pChr = sCharMgr.load(iter->first);
		if (pChr.isNull())
		{
			*packet << uint32(0)
				<< uint8(0)
				<< uint8(0)
				<< uint8(0)
				<< uint32(0)
				<< double(0)
				<< double(0)
				<< double(0)
				<< uint8(0)
				<< int8(0);
		}
		else
		{
			uint32 pid = 0;
			UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
			if (pUser.isNull() == false)
			{
				pid = pUser->getUInt32Field("platform_id");
			}
			*packet << uint32(pChr->getHandle());
			AppendPacketString<uint8>(packet, pChr->getStringField("name"));	// 名字
			AppendPacketString<uint8>(packet, pChr->getStringField("desc"));	// 头像

			sGLMgr.PacketPlayerSameInfo(packet, pChr);							// 地址
			*packet << uint32(pid);
			double j = 0, w = 0, h = 0;
			sGLMgr.GetUserLongitudeAndLatitude(pid, j, w, h);
			*packet << (j) << (w) << (h);
			WSSocketPtr socket = pChr->getSocket();
			String ip = "";
			if (!socket.isNull())
			{
				ip = socket->GetIP();
			}
			AppendPacketString<uint8>(packet, ip);
			*packet << int8(pChr->getUInt32Field("sex"));
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_MaPaiInfo = 0x251A,			//马牌
bool ProtocolsManager::CreateMJMaPaiInfoPacket(WorldPacket * packet, std::vector< std::vector<uint8> > vecMaPaiList, std::vector< std::vector<uint8> > vecZhongMaList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_MaPaiInfo);
	*packet << uint16(SMSS_MJ_MaPaiInfo) << uint16(6);
	
	*packet << uint8(vecMaPaiList.size());
	for (uint8 i = 0; i < vecMaPaiList.size(); i++)
	{
		*packet << uint8(i);
		*packet << uint8(vecMaPaiList[i].size());
		for (uint8 t = 0; t < vecMaPaiList[i].size(); t++)
		{
			*packet << uint8(vecMaPaiList[i][t]);

		}
	}

	*packet << uint8(vecZhongMaList.size());
	for (uint8 i = 0; i < vecZhongMaList.size(); i++)
	{
		*packet << uint8(i);
		*packet << uint8(vecZhongMaList[i].size());
		for (uint8 t = 0; t < vecZhongMaList[i].size(); t++)
		{
			*packet << uint8(vecZhongMaList[i][t]);
		}
	}
	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_TingPaiList = 0x251B,			//听牌列表
bool ProtocolsManager::CreateMJTingPaiListPacket(WorldPacket * packet, std::vector<uint8> vecTingList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_TingPaiList);
	*packet << uint16(SMSS_MJ_TingPaiList) << uint16(6)
		<< uint8(vecTingList.size());
	for (uint8 i = 0; i < vecTingList.size(); i++)
	{
		*packet << vecTingList[i];
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_ScoreChange = 0x251D,				//分数变更
bool ProtocolsManager::CreateMJScoreChangePacket(WorldPacket * packet, std::vector<MJScoreChange> vecScoreChangeList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_ScoreChange);
	*packet << uint16(SMSS_MJ_ScoreChange) << uint16(6)
		<< uint8(vecScoreChangeList.size());
	for (uint8 i = 0; i < vecScoreChangeList.size(); i++)
	{
		*packet << uint8(i);
		*packet << vecScoreChangeList[i].nScoreChange;
		*packet << vecScoreChangeList[i].nScore;
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_ConstantlyCale = 0x251E,			//及时输赢
bool ProtocolsManager::CreateMJConstantlyCalePacket(WorldPacket * packet, std::vector<MJConstantlyCale> vecTablePlayerList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_ConstantlyCale);
	*packet << uint16(SMSS_MJ_ConstantlyCale) << uint16(6)
		<< uint8(vecTablePlayerList.size());
	for (uint8 i = 0; i < vecTablePlayerList.size(); i++)
	{
		*packet << uint8(vecTablePlayerList[i].ui8Kind);
		*packet << uint8(vecTablePlayerList[i].ui8Type);
		*packet << uint8(vecTablePlayerList[i].ui8FanShu);
		*packet << uint8(vecTablePlayerList[i].vecPlayerScore.size());
		for (uint8 k = 0; k < vecTablePlayerList[i].vecPlayerScore.size(); k++)
		{
			*packet << uint8(k);
			*packet << int(vecTablePlayerList[i].vecPlayerScore[k]);
		}
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_ChooseSwapPosNotify = 0x251F,			//通知玩家选换牌位置
bool ProtocolsManager::CreateMJChooseSwapPosNotifyPacket(WorldPacket * packet, const uint8 & ui8Pos, const uint32 & ui32LeftTime)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_ChooseSwapPosNotify);
	*packet << uint16(SMSS_MJ_ChooseSwapPosNotify) << uint16(6)
		<< uint8(ui8Pos)
		<< uint8(ui32LeftTime / 1000);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_BankerChooseSwapPos = 0x2520,			//玩家选择换牌位置
bool ProtocolsManager::CreateMJPlayerChooseSwapPosPacket(WorldPacket * packet, const uint8 & ui8Pos, const uint8 & ui8Type, const uint8 & ui8Result)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_BankerChooseSwapPos);
	*packet << uint16(SMSS_MJ_BankerChooseSwapPos) << uint16(6)
		<< uint8(ui8Pos)
		<< ui8Type
		<< ui8Result;


	packet->SetLength(packet->size());
	return true;
}

//SMSS_MJ_HuaPaiList = 0x2521,					//玩家花牌列表
bool ProtocolsManager::CreateMJPlayerHuaPaiListPacket(WorldPacket * packet, const uint8 & ui8Pos, std::vector<uint8> vecHuaPaiList)
{
	if (!packet)
		return false;
	packet->clear();
	packet->SetOpcode(SMSS_MJ_HuaPaiList);
	*packet << uint16(SMSS_MJ_HuaPaiList) << uint16(6)
		<< uint8(ui8Pos)
		;
	*packet << uint8(vecHuaPaiList.size());
	for (uint8 i = 0; i < vecHuaPaiList.size(); i++)
	{
		*packet << uint8(vecHuaPaiList[i]);
	}


	packet->SetLength(packet->size());
	return true;
}



//===============================俱乐部相关begin==========================================
// 俱乐部资料信息 0x2100
bool ProtocolsManager::CreateClubNormalInfoPacket(WorldPacket * packet, CenterClub & cc)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_NORMALINFO);
	*packet << uint16(SMSG_CLUB_NORMALINFO) << uint16(0)
			<< uint32(cc.club_id)						// 俱乐部ID
			<< uint32(cc.show_id)						// 俱乐部显示ID
			<< uint32(cc.owner_pid)						// 创建者PID
			<< uint32(cc.rank)							// 俱乐部星级(1到9）
			<< uint32(cc.badge_icon)					// 图标ID
			<< uint32(cc.curr_member)					// 当前成员数量
			<< uint32(cc.max_member);					// 最大成员数量
	
	AppendPacketString<uint8>(packet, cc.name);			// 俱乐部名称
	AppendPacketString<uint8>(packet, cc.owner_nick);	// 俱乐部创建者名称
	AppendPacketString<uint8>(packet, cc.city);			// 俱乐部地区信息
	AppendPacketString<uint8>(packet, cc.expiry_date);	// 俱乐部有效期
	AppendPacketString<uint16>(packet, cc.notice);		// 俱乐部公告信息
	AppendPacketString<uint16>(packet, cc.desc);		// 俱乐部简介信息
	
	packet->SetLength(packet->size());
	return true;
}

// 俱乐部大厅信息 0x2101
bool ProtocolsManager::CreateClubHallInfoPacket(WorldPacket * packet, CenterClub & cc, std::list<CenterClubMember> lstClubMember, std::list<CenterClubMessage> lstClubMessage, const uint32 & src_pid)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_HALLINFO);
	*packet << uint16(SMSG_CLUB_HALLINFO) << uint16(6)
			<< uint32(cc.club_id)						// 俱乐部ID
			<< uint32(cc.show_id)						// 俱乐部显示ID
			<< uint32(cc.owner_pid)						// 创建者PID
			<< uint32(cc.rank)							// 俱乐部星级(1到9）
			<< uint32(cc.badge_icon)					// 俱乐部图标
			<< uint32(lstClubMember.size());			// 当前成员数量
	
	std::list<CenterClubMember>::iterator itMem, eiMem = lstClubMember.end();
	for(itMem = lstClubMember.begin(); itMem!=eiMem; ++itMem)
	{
		*packet << uint32((*itMem).pid)						// 成员PID
				<< uint32((*itMem).status)					// 状态（1 在线 2 离线）
				<< uint32((*itMem).type)					// 类型（0 会员 1 副会长 2 会长）
				<< uint32((*itMem).play_loop);				// 游戏局数
		
		String strRemarkLabel = "";
		String strGroupName = "";
		CenterClubRemark ccRemark;
		if(sCenterClubRemarkMgr.GetCenterClubRemark(src_pid, (*itMem).pid, &ccRemark))
		{
			strRemarkLabel = ccRemark.remark_label;
			strGroupName = ccRemark.group_label;
		}
		
		AppendPacketString<uint8>(packet, strRemarkLabel);		// 备注标签
		AppendPacketString<uint8>(packet, strGroupName);		// 分组标签
		AppendPacketString<uint8>(packet, (*itMem).nick);		// 昵称
		AppendPacketString<uint8>(packet, (*itMem).icon_url);	// 头像
		AppendPacketString<uint8>(packet, (*itMem).ll_time);	// 最后登录时间
	}
	
	*packet << uint32(cc.max_member);					// 最大成员数量
	
	AppendPacketString<uint8>(packet, cc.name);			// 俱乐部名称
	AppendPacketString<uint8>(packet, cc.owner_nick);	// 俱乐部创建者名称
	AppendPacketString<uint8>(packet, cc.city);			// 俱乐部地区信息
	AppendPacketString<uint8>(packet, cc.expiry_date);	// 俱乐部有效期
	AppendPacketString<uint16>(packet, cc.notice);		// 俱乐部公告信息
	AppendPacketString<uint16>(packet, cc.desc);		// 俱乐部简介信息
	
	
	// 最近聊天记录
	*packet << uint16(lstClubMessage.size());			// 最近消息条数
	std::list<CenterClubMessage>::iterator iter, ei = lstClubMessage.end();
	for(iter = lstClubMessage.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).message_id)		// 消息序列号
				<< uint32((*iter).owner_cid);		// 玩家角色ID
		
		AppendPacketString<uint8>(packet, (*iter).owner_nick);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).owner_icon);	// 头像url
		AppendPacketString<uint16>(packet, (*iter).message);	// 内容
	}
	
	packet->SetLength(packet->size());
	return true;
}

// 俱乐部列表信息 0x2102
bool ProtocolsManager::CreateClubListInfoPacket(WorldPacket * packet, const uint8 & type, std::list<CenterClub> lCC)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_LIST);
	*packet << uint16(SMSG_CLUB_LIST) << uint16(6)
			<< uint8(type)
			<< uint16(lCC.size());
	
	std::list<CenterClub>::iterator iter, ei = lCC.end();
	for(iter = lCC.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).club_id)						// 俱乐部ID
				<< uint32((*iter).show_id)						// 俱乐部显示ID
				<< uint32((*iter).rank)							// 俱乐部星级(1到9）
				<< uint32((*iter).badge_icon)					// 俱乐部图标ID
				<< uint32((*iter).curr_member)					// 当前成员数量
				<< uint32((*iter).max_member);					// 最大成员数量
		
		AppendPacketString<uint8>(packet, (*iter).name);		// 俱乐部名称
		AppendPacketString<uint8>(packet, (*iter).city);		// 俱乐部地区信息
	}
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_CLUB_CREATE = 0x2103,	创建俱乐部
bool ProtocolsManager::CreateClubCreateResultPacket(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CREATE);
	*packet << uint16(SMSG_CLUB_CREATE) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REQUIREJOIN = 0x2104,	 请求加入俱乐部
bool ProtocolsManager::CreateRequireJoinClubResultPacket(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REQUIREJOIN);
	*packet << uint16(SMSG_CLUB_REQUIREJOIN) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REVIEW = 0x2105,	审核操作（申请加入/带入金额）
bool ProtocolsManager::CreateClubReviewResultPacket(WorldPacket * packet, const uint32 & message_id, const uint8 & type, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REVIEW);
	*packet << uint16(SMSG_CLUB_REVIEW) << uint16(0)
			<< uint32(message_id)
			<< uint8(type)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REVIEW = 0x2106,	审核历史（加入/带入）
bool ProtocolsManager::CreateClubReviewLogsPacket(WorldPacket * packet, const uint32 & club_id, const uint8 & type, std::list<CenterClubLog> lstLogs)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REVIEWLOGS);
	*packet << uint16(SMSG_CLUB_REVIEWLOGS) << uint16(0)
			<< uint32(club_id)
			<< uint8(type)
			<< uint16(lstLogs.size());
	
	Log.Debug("ProtocolsManager::CreateClubReviewLogsPacket","lstLogs size[%u]", lstLogs.size());
	std::list<CenterClubLog>::iterator iter, ei = lstLogs.end();
	for(iter = lstLogs.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).log_id)					// 记录ID
				<< uint32((*iter).pid)
				<< uint8((*iter).status)					// 状态（1 通过 2 拒绝）
				<< uint32((*iter).data1);					// 附加数据（ 带入历史的钱数量）
		
		AppendPacketString<uint8>(packet, (*iter).nick);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).icon);	// 头像
		AppendPacketString<uint8>(packet, (*iter).create_time);
		
		Log.Debug("ProtocolsManager::CreateClubReviewLogsPacket","create_time[%s]", (*iter).create_time.c_str());
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_TAKEIN = 0x2107,	带入金币结果
bool ProtocolsManager::CreateClubTakeinResultPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & coins, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_TAKEIN);
	*packet << uint16(SMSG_CLUB_TAKEIN) << uint16(0)
			<< uint32(club_id)
			<< uint32(coins)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_CLUB_RETURNCOINS = 0x2108,	退分
bool ProtocolsManager::CreateClubReturnCoinsPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & coins, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_RETURNCOINS);
	*packet << uint16(SMSG_CLUB_RETURNCOINS) << uint16(0)
			<< uint32(club_id)
			<< uint32(coins)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_CLUB_BUYPLAYERRANK = 0x2109,	 	购买会员
bool ProtocolsManager::CreateClubBuyPlayerRankResult(WorldPacket * packet, const uint8 & rank, const uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_BUYPLAYERRANK);
	*packet << uint16(SMSG_CLUB_BUYPLAYERRANK) << uint16(0)
			<< uint8(rank)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_CLUB_BUYCLUBRANK = 0x210A,		购买俱乐部星级
bool ProtocolsManager::CreateClubBuyClubRankResult(WorldPacket * packet, const uint32 & club_id, const uint8 & rank, const uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_BUYCLUBRANK);
	*packet << uint16(SMSG_CLUB_BUYCLUBRANK) << uint16(0)
			<< uint32(club_id)
			<< uint8(rank)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_EXITCLUB = 0x210B,			退出公会
bool ProtocolsManager::CreateClubPlayerExitResult(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_EXITCLUB);
	*packet << uint16(SMSG_CLUB_EXITCLUB) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHANGEQUANXIAN = 0x210C,	权限调整
bool ProtocolsManager::CreateClubChangeQuanXianResult(WorldPacket * packet, const uint32 & club_id, const uint32 & pid, const uint8 & member_type, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHANGEQUANXIAN);
	*packet << uint16(SMSG_CLUB_CHANGEQUANXIAN) << uint16(0)
			<< uint32(club_id)
			<< uint32(pid)
			<< uint8(member_type)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_KICKOUT = 0x210D,			踢出玩家
bool ProtocolsManager::CreateClubKickOutResult(WorldPacket * packet, const uint32 & club_id, const uint32 & pid, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_KICKOUT);
	*packet << uint16(SMSG_CLUB_KICKOUT) << uint16(0)
			<< uint32(club_id)
			<< uint32(pid)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHATLIST = 0x210E,			聊天列表信息
bool ProtocolsManager::CreateClubChatlistPacket(WorldPacket * packet, const uint32 & club_id, std::list<CenterClubMessage> lstMessage)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHATLIST);
	*packet << uint16(SMSG_CLUB_CHATLIST) << uint16(0)
			<< uint32(club_id)
			<< uint16(lstMessage.size());
	
	std::list<CenterClubMessage>::iterator iter, ei = lstMessage.end();
	for(iter = lstMessage.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).message_id)		// 消息序列号
				<< uint32((*iter).owner_cid);		// 玩家ID
		
		AppendPacketString<uint8>(packet, (*iter).owner_nick);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).owner_icon);	// 头像url
		AppendPacketString<uint16>(packet, (*iter).message);	// 内容
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHAT = 0x210F,				聊天信息
bool ProtocolsManager::CreateClubChatInfoPacket(WorldPacket * packet, const uint32 & club_id, CenterClubMessage message)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHAT);
	*packet << uint16(SMSG_CLUB_CHAT) << uint16(0)
			<< uint32(club_id)
			<< uint32(message.message_id)
			<< uint32(message.owner_cid);
	
	AppendPacketString<uint8>(packet, message.owner_nick);	// 昵称
	AppendPacketString<uint8>(packet, message.owner_icon);	// 头像url
	AppendPacketString<uint16>(packet, message.message);	// 内容
			
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_TAKEINMEESAGELIST = 0x2110,		俱乐部带入消息列表
bool ProtocolsManager::CreateClubTakeinMessageListPacket(WorldPacket * packet, const uint32 & club_id, std::list<CenterClubMessage> lstMessage)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_TAKEINMEESAGELIST);
	*packet << uint16(SMSG_CLUB_TAKEINMEESAGELIST) << uint16(0)
			<< uint32(club_id)
			<< uint16(lstMessage.size());
	
	std::list<CenterClubMessage>::iterator iter, ei = lstMessage.end();
	for(iter = lstMessage.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).message_id)		// 消息序列号
				<< uint32((*iter).owner_pid)		// 玩家ID
				<< uint32((*iter).takein_coins);	// 附加数据（带入时的金额）
		
		AppendPacketString<uint8>(packet, (*iter).owner_nick);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).owner_icon);	// 头像url
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHENGJIPAIHANG = 0x2113,	俱乐部成绩排行
bool ProtocolsManager::CreateClubChengjiOrderPacket(WorldPacket * packet, const uint32 & club_id, std::list<CenterClubMember> lstMember)
{
	if(!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHENGJIPAIHANG);
	*packet << uint16(SMSG_CLUB_CHENGJIPAIHANG) << uint16(0)
			<< uint32(club_id)
			<< uint16(lstMember.size());
	
	std::list<CenterClubMember>::iterator itMem, eiMem = lstMember.end();
	for(itMem = lstMember.begin(); itMem!=eiMem; ++itMem)
	{
		*packet << uint32((*itMem).pid)									// 成员PID
				<< uint32((*itMem).play_loop)							// 游戏局数
				<< int32((*itMem).curr_result)							// 当前输赢
				<< uint32((*itMem).total_pump)							// 对局费
				<< uint32((*itMem).takein_coins)						// 带入分数
				<< uint32((*itMem).curr_score);							// 当前分数
		
		AppendPacketString<uint8>(packet, (*itMem).nick);				// 昵称
		AppendPacketString<uint16>(packet, (*itMem).icon_url);			// 头像
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_ROOMLIST = 0x2114,			俱乐部房间列表
bool ProtocolsManager::CreateClubRoomListPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & type, std::list<CenterClubRoom> lstRoom)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_ROOMLIST);
	*packet << uint16(SMSG_CLUB_ROOMLIST) << uint16(0)
			<< uint32(club_id)
			<< uint8(type)
			<< uint8(lstRoom.size());
	
	std::list<CenterClubRoom>::iterator iter, ei = lstRoom.end();
	for(iter = lstRoom.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).room_id)							// 房间ID
				<< uint32((*iter).club_id)							// 俱乐部ID
				<< uint8((*iter).type);								// 房间类型
		AppendPacketString<uint16>(packet, (*iter).play_mode);		// 游戏玩法
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CREATEROOM = 0x2115			俱乐部创建房间结果
bool ProtocolsManager::CreateClubCreateRoomResultPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & room_id, String strData, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CREATEROOM);
	*packet << uint16(SMSG_CLUB_CREATEROOM) << uint16(0)
			<< uint32(club_id)
			<< uint32(room_id);

	AppendPacketString<uint16>(packet, strData);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_GOODSLIST = 0x2116,			俱乐部商城道具列表
// bool ProtocolsManager::CreateClubGoodsPacket(WorldPacket * packet, std::list<CenterClubConfig> lstGoods)
// {
	// return true;
// }

//SMSG_CLUB_BUYGOODS = 0x2117,			俱乐部购买商品
bool ProtocolsManager::CreateCLubBuyGoodsResultPacket(WorldPacket * packet, const uint32 & goods_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_BUYGOODS);
	*packet << uint16(SMSG_CLUB_BUYGOODS) << uint16(0)
			<< uint32(goods_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_PLAYERINFO = 0x2118,		俱乐部玩家信息
bool ProtocolsManager::CreateClubPlayerInfoPacket(WorldPacket * packet, CharPtr & pChr)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_PLAYERINFO);
	*packet << uint16(SMSG_CLUB_PLAYERINFO) << uint16(0)
			<< uint8(pChr->getUInt32Field("rank"));			// 俱乐部会员等级
	
	packet->SetLength(packet->size());
	return true;
}

//CMSG_CLUB_CURRSCORE = 0x02119,		俱乐部玩家当前积分
bool ProtocolsManager::CreateClubPlayerCurrScorePacket(WorldPacket * packet, const uint32 & club_id, const uint32 & curr_score)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CURRSCORE);
	*packet << uint16(SMSG_CLUB_CURRSCORE) << uint16(0)
			<< uint32(club_id)
			<< uint32(curr_score);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_DISSOLVE = 0x211A,			解散俱乐部
bool ProtocolsManager::CreateClubDissolvePacket(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_DISSOLVE);
	*packet << uint16(SMSG_CLUB_DISSOLVE) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHANGECLUBINFO = 0x211B,	修改俱乐部信息
bool ProtocolsManager::CreateClubChangeInfoResultPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & type, String & strData, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHANGECLUBINFO);
	*packet << uint16(SMSG_CLUB_CHANGECLUBINFO) << uint16(0)
			<< uint32(club_id)						// 俱乐部ID
			<< uint8(type);							// 修改类型（1 简介 2 公告）
	
	AppendPacketString<uint16>(packet, strData);	// 修改内容
	*packet << uint8(result);						// 结果
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_DDZ_CHANNELLISTINFO = 0x2037,	// 斗地主牌桌列表信息
bool ProtocolsManager::CreateDDZChannelListInfoPacket(WorldPacket * packet, const Json::Value & val)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_DDZ_CHANNELLISTINFO);
	*packet << uint16(SMSG_DDZ_CHANNELLISTINFO) << uint16(0)
			<< uint16(val.size());
	
	for(Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		*packet << uint32((*iterVal)["channel_id"].asUInt())	// 牌桌ID
				<< uint8((*iterVal)["start"].asUInt())			// 是否开始（0 否 1 是）
				<< uint8(0/* (*iterVal)["lock"].asUInt() */);	// 是否上锁（0 否 1 是）
		
		uint8 player_count = 0;
		if((*iterVal).isMember("players"))
			player_count = (*iterVal)["players"].size();
		
		*packet << uint8(player_count);
		if(player_count)
		{
			for(Json::Value::iterator itV2=(*iterVal)["players"].begin(); itV2!=(*iterVal)["players"].end(); ++iterVal)
			{
				*packet << uint8((*itV2)["pos"].asUInt())			// 座位
						<< uint8((*itV2)["ready"].asUInt());		// 是否准备
				
				AppendPacketString<uint8>(packet, (*itV2)["name"].asString());	// 昵称
				AppendPacketString<uint8>(packet, (*itV2)["icon"].asString());	// 头像
			}
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REMARKINFO = 0x211C,		玩家备注信息
bool ProtocolsManager::CreatePlayerClubRemarkInfoPacket(WorldPacket * packet, CenterClubLabel & ccLabel, std::list<CenterClubRemark> lstClubRemark)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REMARKINFO);
	*packet << uint16(SMSG_CLUB_REMARKINFO) << uint16(0);
	
	// 分组列表和名称
	Json::Value valGroup;
	Json::Reader reader;
	reader.parse(ccLabel.group_label, valGroup);
	
	*packet << uint8(valGroup.size());
	for(Json::Value::iterator iterVal=valGroup.begin(); iterVal!=valGroup.end(); ++iterVal)
	{
		AppendPacketString<uint8>(packet, (*iterVal).asString());
	}
	
	// 备注玩家列表
	*packet << uint16(lstClubRemark.size());
	std::list<CenterClubRemark>::iterator iter, ei = lstClubRemark.end();
	for(iter = lstClubRemark.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).remark_id)		// 备注信息序列号
				<< uint32((*iter).dest_pid);		// 目标玩家PID
		
		AppendPacketString<uint8>(packet, (*iter).dest_nick);		// 目标玩家昵称
		AppendPacketString<uint8>(packet, (*iter).dest_icon);		// 目标玩家头像
		
		AppendPacketString<uint8>(packet, (*iter).group_label);		// 分组信息
		
		AppendPacketString<uint8>(packet, (*iter).remark_label);	// 备注标签
		AppendPacketString<uint16>(packet, (*iter).remark_info);	// 备注信息
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_ADDREMARK = 0x211D,			设置玩家备注信息
bool ProtocolsManager::CreateSetPlayerClubRemarkResultPacket(WorldPacket * packet, const uint32 & dest_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_ADDREMARK);
	*packet << uint16(SMSG_CLUB_ADDREMARK) << uint16(0)
			<< uint32(dest_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHANGEGROUPNAME = 0x211E,	修改备注分组名称
bool ProtocolsManager::CreateChangeClubGroupLabelPacket(WorldPacket * packet, const uint8 & index, String & strName, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CHANGEGROUPNAME);
	*packet << uint16(SMSG_CLUB_CHANGEGROUPNAME) << uint16(0)
			<< uint8(index);
	
	AppendPacketString<uint16>(packet, strName);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_ADDREMARKLABEL = 0x211F,	添加标签名称
bool ProtocolsManager::CreateAddLabelNameResultPacket(WorldPacket * packet, String & strLabelName, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_ADDREMARKLABEL);
	*packet << uint16(SMSG_CLUB_ADDREMARKLABEL) << uint16(0);
	
	AppendPacketString<uint16>(packet, strLabelName);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REMOVEREMARKLABEL = 0x2120,	移除标签名称
bool ProtocolsManager::CreateRemoveLabelNameResultPacket(WorldPacket * packet, String & strLabelName, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REMOVEREMARKLABEL);
	*packet << uint16(SMSG_CLUB_REMOVEREMARKLABEL) << uint16(0);
	
	AppendPacketString<uint16>(packet, strLabelName);
	*packet << uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REMOVEREMARKPLAYER = 0x2121,移除备注玩家信息
bool ProtocolsManager::CreateRemoveRemarkPlayerPacket(WorldPacket * packet, const uint32 & dest_pid, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_REMOVEREMARKPLAYER);
	*packet << uint16(SMSG_CLUB_REMOVEREMARKPLAYER) << uint16(0)
			<< uint32(dest_pid)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_PLAYERDETAILS = 0x2122,		俱乐部玩家详细信息
bool ProtocolsManager::CreateClubPlayerDetailsPacket(WorldPacket * packet, CharPtr & pChr, String & remark_info)
{
	if (!packet || pChr.isNull())
		return false;
	
	uint32 pid = 0;
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
		pid = pUser->getUInt32Field("platform_id");
	
	uint32 curr_charm = 0;
	AICreatureBaseInterface * pChrBaseInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrBaseInter)
		curr_charm = pChrBaseInter->GetXMLData("CLUB_CHARM");
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_PLAYERDETAILS);
	*packet << uint16(SMSG_CLUB_PLAYERDETAILS) << uint16(0)
			<< uint32(pChr->getHandle())								// 角色ID
			<< uint32(pid)												// 玩家PID
			<< uint32(curr_charm)										// 当前魅力值
			<< uint32(pChr->getUInt32Field("record_1000"));				// 当前金币
	
	AppendPacketString<uint8>(packet, pChr->getStringField("name"));	// 玩家昵称
	AppendPacketString<uint16>(packet, pChr->getStringField("desc"));	// 玩家头像
	
	String sign_name = "";
	GameBank pBank;
	if(sBankMgr.GetRealBank(pid, pBank) == enGetPlayerInfoByPid_Sucess)
	{
		Json::Value val;
		Json::Reader reader;
		reader.parse(pBank.sdata2, val);
		
		if(val.isMember("签名"))
			sign_name = val["签名"].asString();
	}
	
	AppendPacketString<uint16>(packet, sign_name);						// 签名
	
	AppendPacketString<uint16>(packet, remark_info);					// 备注信息
	sGLMgr.PacketPlayerSameInfo(packet, pChr);							// 物理地址
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CHOOSESEATBATTLELIST = 0x2123, 	俱乐部选座房牌局列表
bool ProtocolsManager::CreateClubChooseSeatBattleListPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & room_id, const uint16 & total_count, 
																	const uint16 & offset, const uint16 & num, std::list<CenterBattle> lstBattles)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CLUB_CHOOSESEATBATTLELIST);
	*packet << uint16(SMSG_CLUB_CHOOSESEATBATTLELIST) << uint16(0)
			<< uint32(club_id)
			<< uint32(room_id)
			<< uint16(total_count)
			<< uint16(offset)
			<< uint16(num)
			<< uint16(lstBattles.size());
	
	std::list<CenterBattle>::iterator iter, ei = lstBattles.end();
	for(iter = lstBattles.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).cb_id)			// 组局ID
				<< uint8((*iter).max_player)		// 最大人数
				<< uint8((*iter).status)			// 状态（3 等待 4 游戏中）
				<< uint32((*iter).base_coins);		// 底分
		
		AppendPacketString<uint8>(packet, (*iter).join_code);	// 房间号
		AppendPacketString<uint16>(packet, (*iter).sdata2);		// 玩法设定
		
		Json::Reader reader;
		Json::Value val;
		reader.parse((*iter).player, val);
		*packet << uint8(val.size());
		
		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			uint8 pos = 255;
			if((*iterVal).isMember("pos"))
				pos = (*iterVal)["pos"].asUInt();
			
			*packet << uint32((*iterVal)["pid"].asUInt())					// PID
					<< uint8((*iterVal)["player_status"].asUInt())			// 状态
					<< uint8(pos);											// 座位
			
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint16>(packet, string_url_decode((*iterVal)["desc"].asString()));
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_BATTLEHISTORYLOG = 0x2124,	俱乐部历史战绩
bool ProtocolsManager::CreateClubBattleHistoryPacket(WorldPacket * packet, const uint32 & club_id, const uint32 & offset, const uint32 & total_num, std::list<CenterBattleLog> logs)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CLUB_BATTLEHISTORYLOG);
	*packet << uint16(SMSG_CLUB_BATTLEHISTORYLOG) << uint16(0)
			<< uint32(club_id)
			<< uint32(total_num)
			<< uint32(offset)
			<< uint16(logs.size());
	
	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for(iter = logs.begin(); iter!=ei; ++iter)
	{
		if((*iter).club_room_id)
		{
			*packet << uint32((*iter).club_room_id);							// 房间ID
			*packet << uint32((*iter).cb_id);									// 组局ID
		}
		else
		{
			*packet << uint32(StringConverter::parseUnsignedInt(sCenterBattleMgr.GetCenterBattleJoinCode((*iter).cb_id)));		// 房间ID
			*packet << uint32((*iter).cb_id);									// 组局ID
		}
		
		AppendPacketString<uint8>(packet, (*iter).create_time);				// 开始时间
		AppendPacketString<uint16>(packet, (*iter).sdata2);					// 游戏玩法说明
		
		Json::Reader reader;
		Json::Value val;
		reader.parse((*iter).sdata5, val);
		*packet << uint16(val.size());										// 玩家数量
		
		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			*packet << uint32((*iterVal)["pid"].asUInt());											// PID
			
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));	// 昵称
			AppendPacketString<uint16>(packet, string_url_decode((*iterVal)["desc"].asString()));	// 头像
			
			*packet << int32((*iterVal)["winlose"].asInt())											// 成绩输赢
					<< uint32((*iterVal)["total_pump"].asInt())										// 成绩抽水
					<< uint32((*iterVal)["takein_coins"].asInt())									// 带入金额
					<< uint16((*iterVal)["player_count"].asUInt());									// 游戏次数
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_REVIEWCOUNT = 0x2125,		俱乐部审核消息数量（用于显示审核旁边的红点）
bool ProtocolsManager::CreateClubMessageListCountPacket(WorldPacket * packet, const uint32 & club_id, const uint8 & type, const uint16 & count, String & strCLubName, bool bRequire)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->reserve(32);
	packet->SetOpcode(SMSG_CLUB_REVIEWCOUNT);
	*packet << uint16(SMSG_CLUB_REVIEWCOUNT) << uint16(0)
			<< uint32(club_id)
			<< uint8(type)
			<< uint8(bRequire)			// 是否客户端请求（0 否 1 是）
			<< uint16(count);
	
	AppendPacketString<uint8>(packet, strCLubName);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_JOINMEESAGELIST = 0x2126,		俱乐部加入消息列表
bool ProtocolsManager::CreateClubJoinMessageListPacket(WorldPacket * packet, const uint32 & club_id, std::list<CenterClubMessage> lstMessage)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_CLUB_JOINMEESAGELIST);
	*packet << uint16(SMSG_CLUB_JOINMEESAGELIST) << uint16(0)
			<< uint32(club_id)
			<< uint16(lstMessage.size());
	
	std::list<CenterClubMessage>::iterator iter, ei = lstMessage.end();
	for(iter = lstMessage.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).message_id)		// 消息序列号
				<< uint32((*iter).owner_pid);		// 玩家ID
		
		AppendPacketString<uint8>(packet, (*iter).owner_nick);	// 昵称
		AppendPacketString<uint8>(packet, (*iter).owner_icon);	// 头像url
		
		AppendPacketString<uint8>(packet, (*iter).target_nick);	// 推荐人昵称
		AppendPacketString<uint8>(packet, (*iter).message);		// 验证信息
	}
	
	packet->SetLength(packet->size());
	return true;
}

// CMSG_CLUB_EXITCOINSLOGS = 0x2127,	俱乐部退分历史
bool ProtocolsManager::CreateClubExitCoinsLogsPacket(WorldPacket * packet, const uint32 & club_id, std::list<CenterClubLog> lstLogs)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(CMSG_CLUB_EXITCOINSLOGS);
	*packet << uint16(CMSG_CLUB_EXITCOINSLOGS) << uint16(0)
			<< uint32(club_id)
			<< uint16(lstLogs.size());
	
	std::list<CenterClubLog>::iterator iter, ei = lstLogs.end();
	for(iter = lstLogs.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).log_id)							// 记录ID
				<< uint32((*iter).pid)
				<< uint8((*iter).status)							// 状态
				<< int32((*iter).data1)								// 成绩金额
				<< uint32((*iter).data2)							// 局数
				<< uint32((*iter).data3)							// 带入金额
				<< uint32((*iter).data4);							// 抽水金额
		
		AppendPacketString<uint8>(packet, (*iter).nick);			// 昵称
		AppendPacketString<uint16>(packet, (*iter).icon);			// 头像
		AppendPacketString<uint8>(packet, (*iter).create_time);
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_MTFCLUBINFO = 0x2129,		满天星俱乐部信息
bool ProtocolsManager::CreateMTFClubInfoPacket(WorldPacket * packet, CenterClub & club, std::list<CenterClubMember> lstManger, std::list<CenterClubMember> lstMember)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_MTFCLUBINFO);
	*packet << uint16(SMSG_CLUB_MTFCLUBINFO) << uint16(0)
			<< uint32(club.club_id)						// 俱乐部ID
			<< uint32(club.show_id)						// 俱乐部显示ID
			<< uint32(club.owner_pid)					// 创建者PID
			<< uint32(club.curr_member)					// 当前成员数量
			<< uint32(club.max_member)					// 最大成员数量
			<< uint32(club.activity_value);				// 公会资金
	
	AppendPacketString<uint8>(packet, club.name);		// 俱乐部名称
	AppendPacketString<uint8>(packet, club.owner_nick);	// 俱乐部创建者名称
	AppendPacketString<uint8>(packet, club.desc);		// 俱乐部简介
	
	// 管理数量
	*packet << uint8(lstManger.size());
	std::list<CenterClubMember>::iterator iter, ei = lstManger.end();
	for(iter = lstManger.begin(); iter!=ei; ++iter)
	{
		AppendPacketString<uint8>(packet, (*iter).nick);
	}
	
	// 成员数量
	*packet << uint16(lstMember.size());
	std::list<CenterClubMember>::iterator itMem, eiMem = lstMember.end();
	for(itMem = lstMember.begin(); itMem!=eiMem; ++itMem)
	{
		*packet << uint32((*itMem).pid)							// 成员PID
				<< uint32((*itMem).status)						// 状态（1 在线 2 离线）
				<< uint32((*itMem).type);						// 类型（0 会员 1 副会长 2 会长）
		
		AppendPacketString<uint8>(packet, (*itMem).nick);		// 昵称
		AppendPacketString<uint8>(packet, (*itMem).icon_url);	// 头像
		AppendPacketString<uint8>(packet, (*itMem).ll_time);	// 最后登录时间
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_HISTORYCHENGJI = 0x212A,	俱乐部历史成绩
bool ProtocolsManager::CreateClubHistoryChengJiPacket(WorldPacket * packet, stClubHistoryBattle stCHB)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_HISTORYCHENGJI);
	*packet << uint16(SMSG_CLUB_HISTORYCHENGJI) << uint16(0)
			<< uint32(stCHB.club_id)			// 俱乐部ID
			<< uint8(stCHB.day)					// 天数（0 表示今天）
			<< uint32(stCHB.battle_count)		// 开房数
			<< uint32(stCHB.use_fangka)			// 房卡消耗
			<< uint16(stCHB.vPlayers.size());	// 玩家数量
	
	Log.Debug("ProtocolsManager::CreateClubHistoryChengJiPacket","club_id[%u] battle_count[%u] use_fangka[%u]", stCHB.club_id, stCHB.battle_count, stCHB.use_fangka);
	std::vector<stClubHistoryBattlePlayer>::iterator iter, ei = stCHB.vPlayers.end();
	for(iter = stCHB.vPlayers.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).src_pid)					// PID
				<< uint32((*iter).count)					// 游戏局数
				<< int32((*iter).winLose);					// 输赢分数
		
		AppendPacketString<uint8>(packet, (*iter).nick);	// 昵称	
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CREATEMTF = 0x212B,			// 创建满天飞俱乐部
bool ProtocolsManager::CreateClubCreateMTFResultPacket(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CREATEMTF);
	*packet << uint16(SMSG_CLUB_CREATEMTF) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	Log.Debug("ProtocolsManager::CreateClubCreateMTFResultPacket","club_id[%u] result[%u]", club_id, result);
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_LISTMTF = 0x212C,			俱乐部列表信息-满天飞
bool ProtocolsManager::CreateClubListInfoMTFPacket(WorldPacket * packet, const uint8 & type, std::list<CenterClub> lCC)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_LISTMTF);
	*packet << uint16(SMSG_CLUB_LISTMTF) << uint16(6)
			<< uint8(type)
			<< uint16(lCC.size());
	
	std::list<CenterClub>::iterator iter, ei = lCC.end();
	for(iter = lCC.begin(); iter!=ei; ++iter)
	{
		*packet << uint32((*iter).club_id)						// 俱乐部ID
				<< uint32((*iter).show_id)						// 俱乐部显示ID
				<< uint32((*iter).curr_member)					// 当前成员数量
				<< uint32((*iter).max_member);					// 最大成员数量
		
		AppendPacketString<uint8>(packet, (*iter).owner_nick);	// 俱乐部创建者名称
		AppendPacketString<uint8>(packet, (*iter).name);		// 俱乐部名称
		AppendPacketString<uint16>(packet, (*iter).desc);		// 俱乐部描述信息
	}
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_CREATEFASTMODE = 0x212D,	创建快速开房配置
bool ProtocolsManager::CreateClubFastModeCreatePacket(WorldPacket * packet, const uint32 & club_id, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_CREATEFASTMODE);
	*packet << uint16(SMSG_CLUB_CREATEFASTMODE) << uint16(0)
			<< uint32(club_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_DELETEFASTMODE = 0x212E,	删除快速开房配置
bool ProtocolsManager::CreateClubFastModeDeletePacket(WorldPacket * packet, const uint32 & club_id, const uint8 & index, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_DELETEFASTMODE);
	*packet << uint16(SMSG_CLUB_DELETEFASTMODE) << uint16(0)
			<< uint32(club_id)
			<< uint8(index)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSG_CLUB_GETFASTMODE = 0x212F,		获取快速开房配置
bool ProtocolsManager::CreateClubFastModeListPacket(WorldPacket * packet, const uint32 & club_id, Json::Value & val)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_CLUB_GETFASTMODE);
	*packet << uint16(SMSG_CLUB_GETFASTMODE) << uint16(0)
			<< uint32(club_id)
			<< uint8(val.size());
	
	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		AppendPacketString<uint16>(packet, (*iterVal).asString());
	}
	
	packet->SetLength(packet->size());
	return true;
}

//================================俱乐部相关end===========================================

// SMSG_COMMON_CONFIGMISSIONLIST = 0x2200, 	// 配置任务列表
bool ProtocolsManager::CreateCommonConfigMissionListPacket(WorldPacket * packet, String & strParams, const uint8 & type)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_COMMON_CONFIGMISSIONLIST);
	*packet << uint16(SMSG_COMMON_CONFIGMISSIONLIST) << uint16(0)
			<< uint8(type);
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strParams, val);
	
	Log.Debug("ProtocolsManager::CreateCommonConfigMissionListPacket","strParams[%s]", strParams.c_str());
	
	uint8 group_mission_count = 0;
	*packet << uint8(val.size());	// 任务种类数量
	for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
	{
		if(type && type != (*iterVal)["type"].asUInt())
			continue;
		
		*packet << uint8((*iterVal)["type"].asUInt())			// 任务类型
				<< uint8((*iterVal)["status"].asUInt());		// 任务状态
		
		Log.Debug("ProtocolsManager::CreateCommonConfigMissionListPacket","type[%u] status[%u]", (*iterVal)["type"].asUInt(), (*iterVal)["status"].asUInt());
		if((*iterVal).isMember("items"))
		{
			*packet << uint8((*iterVal)["items"].size());		// 奖励道具种类
			Log.Debug("ProtocolsManager::CreateCommonConfigMissionListPacket","items[%u]", (*iterVal)["items"].size());

			for(Json::Value::iterator iterItems = (*iterVal)["items"].begin(); iterItems != (*iterVal)["items"].end(); ++iterItems)
			{
				Log.Debug("ProtocolsManager::CreateCommonConfigMissionListPacket","msid[%u] num[%u]", (*iterItems)["msid"].asUInt(), (*iterItems)["num"].asUInt());
				*packet << uint32((*iterItems)["msid"].asUInt())
						<< uint32((*iterItems)["num"].asUInt());
			}
		}
		else
		{
			*packet << uint8(0);
		}
		
		if((*iterVal).isMember("missions"))
		{
			*packet << uint8((*iterVal)["missions"].size());		// 奖励道具种类
			for(Json::Value::iterator iterMissions = (*iterVal)["missions"].begin(); iterMissions != (*iterVal)["missions"].end(); ++iterMissions)
			{
				*packet << uint8((*iterMissions)["index"].asUInt())			// 任务ID
						<< uint8((*iterMissions)["sub_type"].asUInt())		// 子类型
						<< uint8((*iterMissions)["status"].asUInt())		// 任务状态（1 进行中 2 可领 3 已领）
						<< uint8((*iterMissions)["curr_count"].asUInt())	// 已完成进度
						<< uint8((*iterMissions)["need_count"].asUInt())	// 总进度
						<< uint8((*iterMissions)["register_day"].asUInt());	// 注册后几天任务
					
					AppendPacketString<uint8>(packet, (*iterMissions)["name"].asString());
					AppendPacketString<uint16>(packet, (*iterMissions)["content"].asString());
					
					// 单个任务奖励道具数量
					if((*iterMissions).isMember("items"))
					{
						*packet << uint8((*iterMissions)["items"].size());		// 奖励道具种类
						for(Json::Value::iterator iterItems = (*iterMissions)["items"].begin(); iterItems != (*iterMissions)["items"].end(); ++iterItems)
						{
							*packet << uint32((*iterItems)["msid"].asUInt())
									<< uint32((*iterItems)["num"].asUInt());
						}
					}
					else
					{
						*packet << uint8(0);
					}
			}
		}
		else
		{
			*packet << uint8(0);
		}
		
		++group_mission_count;
	}
	
	packet->SetOffset(5, group_mission_count);
	packet->SetLength(packet->size());
	return true;
}

// SMSG_COMMON_CONFIGMISSIONGET = 0x2201,	// 领取配置任务
bool ProtocolsManager::CreateCommonConfigMissionGetPacket(WorldPacket * packet, const uint32 & type, const uint32 & index, const uint8 & result)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_COMMON_CONFIGMISSIONGET);
	*packet << uint16(SMSG_COMMON_CONFIGMISSIONGET) << uint16(0)
			<< uint8(type)
			<< uint8(index)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

// SMSG_COMMON_UPDATECONFIGMISSIONSTATUS = 0x2202,		// 任务状态更新
bool ProtocolsManager::CreateCommonConfigMissionStatusUpdatePacket(WorldPacket * packet, const uint32 & type, const uint32 & index, const uint8 & status)
{
	if (!packet)
		return false;
	
	packet->clear();
	packet->SetOpcode(SMSG_COMMON_UPDATECONFIGMISSIONSTATUS);
	*packet << uint16(SMSG_COMMON_UPDATECONFIGMISSIONSTATUS) << uint16(0)
			<< uint8(type)
			<< uint8(index)
			<< uint8(status);
	
	packet->SetLength(packet->size());
	return true;
}


//================================比赛相关begin===========================================

#ifdef CENTERMATCH

//SMSS_CenterMatch_PublicMatchList = 0x2700,				//公开比赛列表
bool ProtocolsManager::CreateCenterMatchPublicMatchListPacket(WorldPacket * packet, std::list<CenterMatch>& CenterMatchList,const uint8 & type)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_PublicMatchList);
	*packet << uint16(SMSS_CenterMatch_PublicMatchList) << uint16(0);
	*packet << uint8(type);
	*packet << uint8(CenterMatchList.size());
	std::list<CenterMatch>::iterator iter, ei = CenterMatchList.end();
	for (iter = CenterMatchList.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).cm_id)							// 比赛id
			<< uint32((*iter).pid)									// 房主pid 
			<< uint8((*iter).match_status)							// 状态
			<< uint32(time(0) - sGLMgr.GetDateTimeSeconds((*iter).create_time))		// 创建时间
			<< uint32((*iter).enter_limit_num)							// 报名人数限制
			<< uint32( (*iter).enter_limit_time == 0 ? 0 : (sGLMgr.GetDateTimeSeconds((*iter).create_time) + (*iter).enter_limit_time) )							// 报名时间限制
			;
		AppendPacketString<uint8>(packet, (*iter).create_time);

		AppendPacketString<uint16>(packet, (*iter).sdata2);
		AppendPacketString<uint8>(packet, (*iter).battle_name);
		*packet << uint32((*iter).now_enter_num);
	}

	packet->SetLength(packet->size());
	return true;
}


//SMSS_CenterMatch_MatchInfo = 0x2702,				//比赛信息
bool ProtocolsManager::CreateCenterMatchInfoPacket(WorldPacket * packet, const uint32 & cm_id, std::map<uint32, CenterMatchChannelInfo> MatchChannel)
{
	if (!packet)
		return false;
#ifdef CENTERMATCH
	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_MatchInfo);
	*packet << uint16(SMSS_CenterMatch_MatchInfo) << uint16(0)
		<< uint32(cm_id);
	CenterMatch cm;
	sCenterMatchMgr.GetCenterMatch(cm_id, &cm);

	*packet << uint16(MatchChannel.size());
	std::map<uint32, CenterMatchChannelInfo>::iterator iter, ei = MatchChannel.end();
	for (iter = MatchChannel.begin(); iter != ei; ++iter)
	{
		CenterMatchChannelInfo & cmc = (*iter).second;
		*packet << uint32(cmc.ChannelId)							// 比赛id
			<< uint32(cmc.TableNumber)								// 房主pid 
			<< uint8(cmc.status)									// 状态
			;
	}

	packet->SetLength(packet->size());
#endif // DEBUG


	return true;
}
//SMSS_CenterMatch_EnrollmentForm = 0x2703,			//报名列表
bool ProtocolsManager::CreateCenterMatchEnrollmentFormPacket(WorldPacket * packet,const uint32 & cm_id,  std::list<CenterMatchPlayer> cmpList)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_EnrollmentForm);
	*packet << uint16(SMSS_CenterMatch_EnrollmentForm) << uint16(0)
		<<uint32(cm_id);
	*packet << uint16(cmpList.size());
	std::list<CenterMatchPlayer>::iterator iter, ei = cmpList.end();
	for (iter = cmpList.begin(); iter != ei; ++iter)
	{
		std::list<UserPtr> temp;
		sUserMgr.getUserList(&temp, 0, 1, "platfrom_id = %d", (*iter).pid);
		UserPtr pUser;
		if (temp.size())
			pUser = temp.front();

		*packet << uint32((*iter).pid);								// pid
		*packet << uint32(pUser.isNull() == false ? pUser->getUInt32Field("char_id") : 0);
		*packet << uint8((*iter).enter_status);					// 报名状态
		AppendPacketString<uint8>(packet, (*iter).name);			//名字
		AppendPacketString<uint8>(packet, (*iter).head);			//头像
		AppendPacketString<uint8>(packet, (*iter).create_time);		//报名时间
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_SignUp = 0x2704,					//报名结果
bool ProtocolsManager::CreateCenterMatchPlayerSignUpPacket(WorldPacket* packet, const uint32 & cm_id,String join_code, const  uint32 & chr_id, uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_SignUp);
	*packet << uint16(SMSS_CenterMatch_SignUp) << uint16(0)
		<< uint32(cm_id);
	AppendPacketString<uint8>(packet, join_code);
	*packet	<< uint32(chr_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_ReviewSignUp = 0x2705,					//审核报名结果
bool ProtocolsManager::CreateCenterMatchReviewSignUpPacket(WorldPacket* packet, const uint32 & cm_id, const  uint32 & chr_id, uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_ReviewSignUp);
	*packet << uint16(SMSS_CenterMatch_ReviewSignUp) << uint16(0)
		<< uint32 (cm_id)
		<< uint32(chr_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_PlayerInfoListInCenter = 0x2706,					//玩家信息
bool ProtocolsManager::CreateCenterMatchPlayerInfoListInCenterPacket(WorldPacket * packet, CharPtr pChr, CenterMatch cm, std::map<uint32, CenterMatchPlayerInfo> MatchPlayer)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_PlayerInfoListInCenter);
	*packet << uint16(SMSS_CenterMatch_PlayerInfoListInCenter) << uint16(0);
	CenterMatchPlayerInfo  player;
	if(MatchPlayer.find(pChr->getHandle()) != MatchPlayer.end())
	 player = MatchPlayer.at(pChr->getHandle());

	*packet << uint32(player.rank);
	*packet << uint32(cm.data2);

	std::map<uint32, CenterMatchPlayerInfo> temp;

	std::map<uint32, CenterMatchPlayerInfo>::iterator iter, ei = MatchPlayer.end();
	for (iter = MatchPlayer.begin(); iter != ei; ++iter)
	{
		temp[iter->second.rank] = iter->second;
	}
	*packet << uint16(temp.size());
	for (iter = temp.begin(); iter != temp.end(); ++iter)
	{
		CenterMatchPlayerInfo & cmp = iter->second;
		CharPtr pPlayer = sCharMgr.load(cmp.char_id);
		*packet << uint32(cmp.pid);
		*packet << uint32(cmp.rank);
		*packet << int32(cmp.score);
		AppendPacketString<uint8>(packet, pPlayer->getCharName());
		AppendPacketString<uint8>(packet, pPlayer->getStringField("desc"));
	}


	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CreateMatch = 0x2707,						//创建比赛
bool ProtocolsManager::CreateCenterMatchCreateMatchPacket(WorldPacket * packet, const uint32 & cm_id, String str, uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_CreateMatch);
	*packet << uint16(SMSS_CenterMatch_CreateMatch) << uint16(0)
		<< uint32(cm_id)
		<< uint8(result);
	AppendPacketString<uint16>(packet, str);
	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_EnterMatch = 0x2708,						//加入比赛
bool ProtocolsManager::CreateCenterMatchEnterMatchPacket(WorldPacket * packet, const uint32 & cm_id,const uint32 & gz_id, uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_EnterMatch);
	*packet << uint16(SMSS_CenterMatch_EnterMatch) << uint16(0)
		<< uint32(cm_id)
		<< uint32(gz_id);
	*packet << uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_PlayerEnterMatchList = 0x2709,						//已经入比赛列表
bool ProtocolsManager::CreateCenterMatchPlayerEnterMatchListPacket(WorldPacket * packet, std::list<CenterMatchPlayer>& playerList)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_PlayerEnterMatchList);
	*packet << uint16(SMSS_CenterMatch_PlayerEnterMatchList) << uint16(0);

	if (playerList.empty())
		*packet << uint32(0);
	else
	{
		CenterMatchPlayer temp = *(playerList.begin());
		*packet << uint32(temp.cm_id);
	}
	

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CenterMatchDissolve = 0x270B,						//解散比赛
bool ProtocolsManager::CreateCenterMatchDissolve(WorldPacket * packet, const uint32 & cm_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_CenterMatchDissolve);
	*packet << uint16(SMSS_CenterMatch_CenterMatchDissolve) << uint16(0)
		<< uint32(cm_id)
		<< uint8(result);


	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CenterMatchWatch = 0x270C,							//比赛观战
bool ProtocolsManager::CreateCenterMatchWatchPacket(WorldPacket * packet, const uint32 & cm_id, const uint32 & channel_id, const uint32 & gz_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_CenterMatchWatch);
	*packet << uint16(SMSS_CenterMatch_CenterMatchWatch) << uint16(0)
			<< uint32(cm_id)
			<< uint32(channel_id)
			<< uint32(gz_id)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CenterMatchLog = 0x270D,							//比赛游戏记录
bool ProtocolsManager::CreateCenterMatchLogPacket(WorldPacket * packet, std::list<CenterMatch> logs, const uint32 & cm_id, const uint16 & total_count, const uint16 & offset)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSS_CenterMatch_CenterMatchLog);
	*packet << uint16(SMSS_CenterMatch_CenterMatchLog) << uint16(0)
		<< uint16(total_count)
		<< uint16(offset)
		<< uint16(logs.size());

	std::list<CenterMatch>::iterator iter, ei = logs.end();
	for (iter = logs.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).cm_id)					// 比赛ID
			<< uint16((*iter).gz_id)						// 分区ID
			<< uint16((*iter).game_id)						// 游戏ID
			<< uint32((*iter).pid)							// 房主PID
			<< uint32((*iter).sponsor_id)						// 赞助商id
			<< uint8((*iter).match_mode)						// 游戏模式
			;
		uint32 use_time = sGLMgr.GetDateTimeSeconds((*iter).end_time ) > 0 ? sGLMgr.GetDateTimeSeconds((*iter).end_time) : sGLMgr.GetDateTimeSeconds((*iter).end_time) - sGLMgr.GetDateTimeSeconds((*iter).create_time);

		*packet << uint32(use_time);							// 用时

		AppendPacketString<uint8>(packet, (*iter).battle_name);		// 游戏名称
		AppendPacketString<uint8>(packet, (*iter).join_code);		// 房间ID
		AppendPacketString<uint8>(packet, (*iter).create_time);		// 开始时间

		std::list<CenterMatchPlayer> playerList;
		sCenterMatchPlayerMgr.GetCenterMatchPlayerList(&playerList, "cm_id = %d and enter_status = %d and status = 255 order by data2", iter->cm_id, enCenterMatchEnterStatus_Passed);

		*packet << uint16(playerList.size());
		std::list<CenterMatchPlayer>::iterator pIter , pEi = playerList.end();

		for (pIter = playerList.begin(); pIter != pEi; ++pIter)
		{
			Json::Reader reader;
			Json::Value val, val_best;
			reader.parse((*pIter).sdata2, val);
			*packet << uint32((*pIter).pid)		//pid
				<< uint32((*pIter).data2)		//名次
				<< int32((*pIter).data4)		//分数
				;
			AppendPacketString<uint8>(packet, string_url_decode(val["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode(val["desc"].asString()));
			AppendPacketString<uint16>(packet, string_url_decode(Json::FastWriter().write(val["json_data"])));
		}


	}

	// 返回客户端请求的组局ID（0 表示所有）
	*packet << uint32(cm_id);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CenterMatchLoopLog = 0x270E,							//比赛游戏记录
bool ProtocolsManager::CreateCenterMatchLoopLogPacket(WorldPacket * packet, std::list<CenterBattleLog> logs, const uint32 & cm_id, const uint32 & channelId, const uint16 & total_count, const uint16 & offset)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSS_CenterMatch_CenterMatchLoopLog);
	*packet << uint16(SMSS_CenterMatch_CenterMatchLoopLog) << uint16(0)
		<< uint16(total_count)
		<< uint16(offset)
		<< uint16(logs.size());

	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for (iter = logs.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).cb_id)					// 组局ID
			<< uint32((*iter).club_room_id)					// 牌桌号
			<< uint32((*iter).club_id)						// 阶段id
			<< uint16((*iter).gz_id)						// 分区ID
			<< uint16((*iter).game_id)						// 游戏ID
			<< uint32((*iter).src_pid)						// 房主PID
			<< uint8((*iter).data12)						// 游戏模式
			<< uint32((*iter).data1)						// 底分
			<< uint32((*iter).data2)						// 翻分
			<< uint16((*iter).data11);						// 封顶倍数翻数

		uint32 use_time = (*iter).data8 > 0 ? (*iter).data8 : time(0) - (*iter).data3;

		*packet << uint32(use_time)							// 用时
			<< uint16((*iter).data4)						// 游戏局数
			<< uint16((*iter).data5)						// 总局数
			<< uint32((*iter).data7)						// 最大赢钱
			<< uint32((*iter).data6);						// 总赢

		AppendPacketString<uint8>(packet, (*iter).sdata1);		// 游戏名称
	
		AppendPacketString<uint8>(packet, (*iter).sdata7);		// 房间ID
		AppendPacketString<uint8>(packet, (*iter).create_time);	// 开始时间

		Json::Reader reader;
		Json::Value val, val_best;
		reader.parse((*iter).sdata5, val);
		reader.parse((*iter).sdata6, val_best);

		// 赢最多玩家昵称，头像
		if (val_best.isMember("win_max"))
		{
			*packet << uint32(val_best["win_max"]["pid"].asUInt());
		}
		else
		{
			*packet << uint32(0);
		}

		// 输最多玩家昵称，头像
		if (val_best.isMember("lose_max"))
		{
			*packet << uint32(val_best["lose_max"]["pid"].asUInt());
		}
		else
		{
			*packet << uint32(0);
		}

		*packet << uint8(val.size());
		Log.Debug("ProtocolsManager::CreateCenterMatchLoopLogPacket", "cb_id[%u] val size[%u]", (*iter).cb_id, val.size());
		for (Json::Value::iterator iterVal = val.begin(); iterVal != val.end(); ++iterVal)
		{
			*packet << uint32((*iterVal)["pid"].asUInt());

			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));

			*packet << int32((*iterVal)["winlose"].asInt())
				<< uint16((*iterVal)["player_count"].asUInt());

			AppendPacketString<uint16>(packet, string_url_decode((*iterVal)["json_data"].asString()));
		}

		// CenterBattle cb;
		// sCenterBattleMgr.GetCenterBattle((*iter).cb_id, &cb);

		// Json::Value valPay;
		// valPay["pay_mode"] = cb.pay_mode;

		// Json::FastWriter w;
		// AppendPacketString<uint16>(packet, w.write(valPay));
	}

	// 返回客户端请求的组局ID（0 表示所有）
	*packet << uint32(cm_id);
	*packet << uint32(channelId);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_CenterMatchBattlelog = 0x270F,							//单局比赛游戏记录
bool ProtocolsManager::CreateCenterMatchBattleLogPacket(WorldPacket * packet, std::list<CenterBattleLog> logs)
{
	if (!packet)
		return false;

	packet->clear();
	// 预开辟空间
	packet->reserve(4096);
	packet->SetOpcode(SMSS_CenterMatch_CenterMatchBattlelog);
	*packet << uint16(SMSS_CenterMatch_CenterMatchBattlelog) << uint16(0);

	CenterBattleLog endLog;
	if (logs.size())
		endLog = logs.back();

	*packet << uint32(endLog.cb_id)							// 组局ID
		<< uint32(endLog.club_room_id)							// 房间号
		<< uint32(endLog.club_id)							//   阶段id
		<< uint32(endLog.data5)							// 房主PID
		<< uint16(endLog.gz_id)							// 分区ID
		<< uint16(endLog.data7);						// 最大轮次
		;
	AppendPacketString<uint8>(packet, endLog.sdata1);						// 游戏名称
	AppendPacketString<uint8>(packet, string_url_decode(endLog.sdata2));	// 房间名称

	Json::Reader reader;
	Json::Value val, val_real;
	reader.parse(endLog.sdata5, val);

	*packet << uint16(logs.size());									// 记录数量
	std::list<CenterBattleLog>::iterator iter, ei = logs.end();
	for (iter = logs.begin(); iter != ei; ++iter)
	{
		*packet << uint32((*iter).battle_log_id)					// 中心组局日志ID
			<< uint16((*iter).data3)							// 轮次ID
			<< uint8((*iter).data6);							// 是否有录像

		AppendPacketString<uint8>(packet, (*iter).create_time);		// 开始时间

		Json::Value valEx;
		reader.parse((*iter).sdata5, valEx);
		if (valEx.isMember("players"))
		{
			*packet << uint8(valEx["players"].size());

			for (Json::Value::iterator iterVal = valEx["players"].begin(); iterVal != valEx["players"].end(); ++iterVal)
			{
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["pid"] = (*iterVal)["pid"].asUInt();
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["name"] = (*iterVal)["name"].asString();
				val_real[StringConverter::toString((*iterVal)["pid"].asUInt())]["desc"] = (*iterVal)["desc"].asString();

				*packet << uint32((*iterVal)["pid"].asUInt());
				*packet << int32((*iterVal)["winlose"].asInt());
				AppendPacketString<uint16>(packet, (*iterVal)["json_data"].asString());
			}
		}
		else
		{
			*packet << uint8(0);
		}
	}

	if (val_real.size())
	{
		*packet << uint8(val_real.size());

		for (Json::Value::iterator iterVal = val_real.begin(); iterVal != val_real.end(); ++iterVal)
		{
			*packet << uint32((*iterVal)["pid"].asUInt());

			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["name"].asString()));
			AppendPacketString<uint8>(packet, string_url_decode((*iterVal)["desc"].asString()));
		}
	}
	else
	{
		*packet << uint8(0);
	}

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_PlayerGiveUpMatch = 0x270A,						//玩家退赛
bool ProtocolsManager::CreateCenterMatchPlayerGiveUpMatchPacket(WorldPacket * packet, const uint32 & cm_id, const uint8 & result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_PlayerGiveUpMatch);
	*packet << uint16(SMSS_CenterMatch_PlayerGiveUpMatch) << uint16(0)
		<< uint32(cm_id)
		<< uint8(result);


	packet->SetLength(packet->size());
	return true;
}


//SMSS_CenterMatch_WaitJoinChannel = 0x2720,					//等待进入牌桌
bool ProtocolsManager::CreateCenterMatchWaitJoinChannelPacket(WorldPacket * packet, uint8 status)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_WaitJoinChannel);
	*packet << uint16(SMSS_CenterMatch_WaitJoinChannel) << uint16(0);
	*packet << uint8(status);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_MatchStage = 0x2721,						//比赛进度
bool ProtocolsManager::CreateCenterMatchStageInofPacket(WorldPacket * packet, CenterMatchLogic* cml)
{
	if (!packet)
		return false;
#ifdef CENTERMATCH
	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_MatchStage);
	*packet << uint16(SMSS_CenterMatch_MatchStage) << uint16(0);
	String stageRule = "";
	if (cml->m_CenterMatchStage.stageMode == enCenterMatchRuleMode_DingJuJiFen)
	{
		stageRule = cml->stageRule;
	}
	*packet << uint8(cml->m_NowStage);
	*packet << uint8(cml->m_MatchStageStatus);

	CenterMatch cm;
	sCenterMatchMgr.GetCenterMatch(cml->m_cm_id, &cm);
	Json::Value val;
	Json::Reader reader;
	Json::FastWriter w;
	reader.parse(cm.sdata2, val);
	val["start_time"] = 0;
	if (cm.enter_limit_time != 0)
	{
		val["start_time"] = uint32(sGLMgr.GetDateTimeSeconds(cm.create_time) + cm.enter_limit_time);
		
	}
	cm.sdata2 = w.write(val);
	AppendPacketString<uint16>(packet, cm.sdata2);

	*packet << cml->m_matchStartWaitTimer;
	*packet << uint32(cm.enter_limit_num);
	*packet << uint32(cm.now_enter_num);


	packet->SetLength(packet->size());
#endif // CENTERMATCH

	
	return true;
}


//SMSS_CenterMatch_JoinChannelNotify = 0x2723,						//通知进入牌桌
bool ProtocolsManager::CreateCenterMatchJoinChannelNotifyPacket(WorldPacket * packet, const uint32 & channel_id)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_JoinChannelNotify);
	*packet << uint16(SMSS_CenterMatch_JoinChannelNotify) << uint16(0)
		<< uint32(channel_id);
	
	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_JoinChannel = 0x2724,						//进入牌桌
bool ProtocolsManager::CreateCenterMatchJoinChannelPacket(WorldPacket * packet, const uint32 & channel_id, const uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_JoinChannel);
	*packet << uint16(SMSS_CenterMatch_JoinChannel) << uint16(0)
		<< uint32(channel_id)
		<< uint8(result);

	packet->SetLength(packet->size());
	return true;
}

//SMSS_CenterMatch_RiseOrDown = 0x2725,						//晋级or淘汰
bool ProtocolsManager::CreateCenterMatchRiseOrDownNotifyPacket(WorldPacket * packet, const uint16 & now_rank, const uint16 & now_playerNum, const uint32 & now_channel, std::map<uint32, uint32> prize, String str, uint8 result)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSS_CenterMatch_RiseOrDown);
	*packet << uint16(SMSS_CenterMatch_RiseOrDown) << uint16(0)
		<< uint16(now_rank)
		<< uint16(now_playerNum)
		<< uint8(result);
	*packet << uint8(prize.size());
	std::map<uint32, uint32>::iterator iter, ei = prize.end();
	for (iter = prize.begin(); iter != ei; ++iter)
	{
		*packet << uint32(iter->first)
			<< uint32(iter->second);
	}
	AppendPacketString<uint8>(packet, str);
	*packet << now_channel;
	//Log.Debug("ProtocolsManager::CreateCenterMatchRiseOrDownNotifyPacket"," now_rank[%d] now_playerNum[%] now_channel[%d]", now_rank, now_playerNum, now_channel);
	packet->SetLength(packet->size());
	return true;
}

// SMSG_REQUIE_MATCHZONELIST = 0x2740,						// 请求赛区列表
bool ProtocolsManager::CreateCenterMatchZoneListPacket(WorldPacket * packet, std::map<uint32, stMatchZone> mapMz)
{
	if (!packet)
		return false;

	packet->clear();
	packet->SetOpcode(SMSG_REQUIE_MATCHZONELIST);
	*packet << uint16(SMSG_REQUIE_MATCHZONELIST) << uint16(0)
			<< uint16(mapMz.size());
	
	std::map<uint32, stMatchZone>::iterator iter, ei = mapMz.end();
	for(iter = mapMz.begin(); iter!=ei; ++iter)
	{
		*packet << uint32(iter->second.zone_id)						// 赛区ID
				<< uint8(iter->second.type)							// 赛区类型
				<< uint32(iter->second.player_num);					// 赛区人数
		
		AppendPacketString<uint8>(packet, iter->second.name);		// 赛区名字
		AppendPacketString<uint8>(packet, iter->second.match_name);	// 比赛名称
		AppendPacketString<uint16>(packet, iter->second.contant);	// 赛区简介
		AppendPacketString<uint16>(packet, iter->second.icon);		// 赛区图标URL
		AppendPacketString<uint16>(packet, iter->second.play_mode);	// 游戏玩法规则JSON
	}
	
	Log.Debug("ProtocolsManager::CreateCenterMatchZoneListPacket","mapMz siz[%u] packet size()", mapMz.size(), packet->size());
	packet->SetLength(packet->size());
	return true;
}

#endif // CENTERMATCH

#ifdef PKPUBLIC
/* --------------------------------------------------扑克相关协议 --------------------------------------------------*/
// SMSG_PUKE_PlayerInfo = 0x3000    玩家信息
bool ProtocolsManager::CreatePKPlayerInfoPacket(WorldPacket * packet, PKBaseTablePlayer * Player)
{
	if (!packet || Player == NULL || Player->player.isNull())
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_PUKE_PlayerInfo);
	*packet << uint16(SMSG_PUKE_PlayerInfo) << uint16(5);

	*packet << uint32(Player->player._handle);
	uint32 money = 0;

	uint32 pid = 0;
	CharPtr pChr = sCharMgr.load(Player->player._handle);
	if (!pChr.isNull())
	{
		if (Player->u8PayModel == 3)
		{
			money = sGLMgr.GetItemNum(pChr, ItemModel_Coins);
			// if (Player->ui32ClubId != 0)
			// {
				// money = sCenterClubMemberMgr.GetMemberCurrCoins(Player->ui32ClubId, pChr);
				// Log.Debug("ProtocolsManager::CreateMJPlayerInfoPacket", "money[%d]", money);
			// }
		}
		UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		if (pUser.isNull())
		{
			pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		}

		if (!pUser.isNull())
			pid = pUser->getUInt32Field("platform_id");
	}
	if (pChr.isNull())
	{
		*packet << int32(0)
			<< uint32(0)
			<< uint8(0)
			<< uint8(Player->u32Pos)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint8(0)
			<< uint32(pid)
			<< double(0)		//经度纬度海拔
			<< double(0)
			<< double(0)
			<< uint8(0);
		*packet << int8(0);

	}
	else
	{
		*packet << int32(Player->i32AllScore)								// 积分
			<< uint32(money)												// 钱
			<< uint8(Player->bIsFangZhu)									// 房主标志
			<< uint8(Player->u32Pos)										// 座位号
			<< uint8(Player->u32ReadyStatus);								// 是否准备

		AppendPacketString<uint8>(packet, pChr->getStringField("name"));	// 名字
		AppendPacketString<uint8>(packet, pChr->getStringField("desc"));	// 头像
																		
		sGLMgr.PacketPlayerSameInfo(packet, pChr);							// 地址
		*packet << uint32(pid);
		double j = 0, w = 0, h = 0;
		sGLMgr.GetUserLongitudeAndLatitude(pid, j, w, h);
		*packet << (j)<< (w)<< (h);
		WSSocketPtr socket = pChr->getSocket();
		String ip = "";
		if (!socket.isNull())
		{
			ip = socket->GetIP();
		}
		AppendPacketString<uint8>(packet, ip);
		*packet << int8(pChr->getUInt32Field("sex"));
	}

	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_PlayerDoList = 0x3001 	玩家可操作列表
bool ProtocolsManager::CreatePKPlayerOperatorListPacket(WorldPacket * packet,std::map<uint32,OperatorList> DoList)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_PlayerDoList);
	*packet << uint16(SMSG_PUKE_PlayerDoList) << uint16(packlen)
			<< uint8(DoList.size());	//可操作类型数量
	
	std::map<uint32,OperatorList>::iterator iter,ei = DoList.end();
	for(iter = DoList.begin(); iter != ei; ++iter)
	{
		*packet << uint8(iter->first)					// 可操作类型（弃牌，比牌，跟注，下注。。。）
				<< uint8(iter->second.bValid)			// 操作类型是否有效
				<< uint8(iter->second.v32OpList.size());	// 可选择操作内容
		
		std::vector<uint32>::iterator iterOP,eiOP = iter->second.v32OpList.end();
		for(iterOP = iter->second.v32OpList.begin(); iterOP!=eiOP; ++iterOP)
		{
			*packet << uint32(*iterOP);
		}
	}
	
	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_PlayerDoResult = 0x3002,						// 玩家操作结果
bool ProtocolsManager::CreatePKPlayerOperatorResultPacket(WorldPacket * packet, const uint8 & model , bool result)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_PlayerDoResult);
	*packet << uint16(SMSG_PUKE_PlayerDoResult) << uint16(packlen)
			<< uint8(model)
			<< uint8(result);
	
	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_PlayerCards = 0x3003,							// 玩家牌信息
bool ProtocolsManager::CreatePKPlayerCardsInfoPacket(WorldPacket * packet, const uint8 & pos, const uint8 & cscnum, const uint8 & cardtype, const uint32 & cardpoint,std::vector<uint16> cards, const uint8 & operatortype)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_PlayerCards);
	*packet << uint16(SMSG_PUKE_PlayerCards) << uint16(packlen)
			<< uint8(pos)
			<< uint8(cardtype)
			<< uint32(cardpoint)
			<< uint8(operatortype)
			<< uint8(cards.size());
			
	for(uint8 i = 0; i < cards.size(); ++i)
	{
		if(i < cscnum)
			*packet << uint8(cards[i]);
		else
			*packet << uint8(0);
	}
	
	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_PlayerChipin = 0x3004,						// 玩家下注总金额
bool ProtocolsManager::CreatePKPlayerChipinInfoPacket(WorldPacket * packet, std::vector<PKBaseTablePlayer> Player)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_PlayerChipin);
	*packet << uint16(SMSG_PUKE_PlayerChipin) << uint16(packlen);
	
	uint8 offset = packet->size();
	uint8 player_num = 0;
	*packet	<< uint8(offset);
	
	std::vector<PKBaseTablePlayer>::iterator iter,ei = Player.end();
	for(iter = Player.begin(); iter!=ei; ++iter)
	{
		if((*iter).player.isNull())
			continue;
		
		if((*iter).u32Status != PuKePlayerGame_GoOn)
			continue;
		uint32 chipinall = 0;
		for(uint32 i = 0; i < (*iter).vstChipInfo.size(); ++i)
		{
			chipinall += (*iter).vstChipInfo[i].ChinpinMuch;
		}
		
		*packet << uint8((*iter).u32Pos)						// 座位号
				<< uint8((*iter).bWatchCard)					// 是否看牌
				<< uint8((*iter).bLetCard)						// 是否弃牌
				<< uint8((*iter).u32WinOrLoser)					// 输赢(0 正常 1 赢 2 输）
				<< uint32(chipinall);							// 总下注金额
				
		++player_num;
	}
	
	packet->SetOffset(offset,player_num);
	
	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_PlayerStartStatus = 0x3005,					// 玩家游戏中状态
bool ProtocolsManager::CreatePKPlayerStartStatusPacket(WorldPacket * packet, const uint8 & pos, const int & chipin, const uint8 & type)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_PlayerStartStatus);
	*packet << uint16(SMSG_PUKE_PlayerStartStatus) << uint16(packlen)
			<< uint8(pos)
			<< uint8(type)
			<< int(chipin);
	
	packet->SetLength(packet->size());
	return true;
}
// SMSG_PUKE_GameCalc = 0x3006,							// 游戏结算信息包
bool ProtocolsManager::CreatePKSendGameCalcPacket(WorldPacket * packet,std::vector<PKBaseTablePlayer> player, PKBaseTablePlayer & pTp, bool result)
{
	if(!packet)
		return false;
	
	int8 packlen = 10;
	packet->clear();
	
	packet->SetOpcode(SMSG_PUKE_GameCalc);
	*packet << uint16(SMSG_PUKE_GameCalc) << uint16(packlen);
	
	uint8 offset = packet->size();
	uint8 player_num = 0;
	*packet	<< uint8(offset);
	
	CharPtr pChr = sCharMgr.load(pTp.player._handle);
	if(pChr.isNull())
		return false;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	std::vector<uint16> comparelist = pTp.vv16ComparePosList;
	
	std::vector<PKBaseTablePlayer>::iterator iter,ei = player.end();
	for(iter = player.begin(); iter!=ei; ++iter)
	{
		if((*iter).player.isNull())
			continue;
		
		if((*iter).u32Status != PuKePlayerGame_GoOn)
			continue;
		
		bool bSelf = false;
		if(pChr->getHandle() == (*iter).player._handle)
			bSelf = true;
		
		*packet << uint8((*iter).u32Pos)						// 座位号
				<< int((*iter).i32WinChip)						// 输赢
				<< uint8((*iter).cards.v16HandCards.size());	// 手牌数量
			
		bool IsReally = false;
		std::vector<uint16> cards;
		if(bSelf)
		{
			if(result)
			{
				if((*iter).bWatchCard || (*iter).bCompareCard)
				{
					IsReally = true;
					cards = (*iter).cards.v16HandCards;
				}
			}
			else
			{
				IsReally = true;
				cards = (*iter).cards.v16HandCards;
			}
			
		}
		else
		{
			if(result)
			{
				if(find(comparelist.begin(),comparelist.end(),(*iter).u32Pos) != comparelist.end())
				{
					IsReally = true;
					cards = (*iter).cards.v16HandCards;
				}
			}
			else
			{
				IsReally = true;
				cards = (*iter).cards.v16HandCards;
			}
			
		}
		
		uint8 cardtype = 0;
		uint32 cardpoint = 0;
		if(IsReally)
		{
			cardtype = (*iter).cards.u32CardType;;
			cardpoint = (*iter).cards.u32MaxPoint;;
		}
		if(!IsReally)
		{
			cards.assign((*iter).cards.v16HandCards.size(),0);
		}
		std::vector<uint16>::iterator itCards,eiCards = cards.end();
		for(itCards = cards.begin(); itCards!=eiCards; ++itCards)
		{
			*packet << uint8(*itCards);		// 牌值
		}
		*packet << uint8(cardtype)			// 牌型
				<< uint32(cardpoint);		// 附加数据

				
		++player_num;
	}
	
	packet->SetOffset(offset,player_num);
	
	packet->SetLength(packet->size());
	return true;
}

#endif

//================================比赛相关end===========================================

